【问题标题】:"Saved photo" alert popping up before the user allows permissions to photo library?在用户允许访问照片库之前弹出“已保存照片”警报?
【发布时间】:2019-02-20 16:00:51
【问题描述】:

当用户点击按钮时,它会在请求用户许可之前立即触发“照片已保存”警报。如果用户单击否,则照片不会保存,但仍会显示警报。在用户允许访问照片库之前,是否有一个 if else 语句可以让我不会弹出警报?

@IBAction func savePhotoClicked(_ sender: Any) {


    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)


    let alert = UIAlertController(title: "Saved!", message: "This wallpaper has been saved.", preferredStyle: .alert)
    let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
    alert.addAction(okAction)
    self.present(alert, animated: true, completion: nil)


}

【问题讨论】:

    标签: ios swift photo


    【解决方案1】:

    您显示警报控制器的方式太快了。对UIImageWriteToSavedPhotosAlbum 的调用是异步的。查看您传递给第二个、第三个和第四个参数的所有nil 值吗?将它们替换为适当的值,这样您就可以在对 UIImageWriteToSavedPhotosAlbum 的调用实际完成时调用警报,并且您可以正确确定图像是否实际保存。

    @IBAction func savePhotoClicked(_ sender: Any) {
        UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil)
    }
    
    @objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
        if let error = error {
            // show error
        } else {
            let alert = UIAlertController(title: "Saved!", message: "This wallpaper has been saved.", preferredStyle: .alert)
            let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
            alert.addAction(okAction)
            self.present(alert, animated: true, completion: nil)
        }
    }
    

    【讨论】:

    • 更好的是,不要调用 UIImageWriteToSavedPhotosAlbum。有一种适当的现代 PHPhotoLibrary 方法可以将图像写入照片库,但不是这样。
    • @matt 这可能是真的,但这个答案解释了为什么 OP 对他们当前的代码有问题。
    • 是的,我没说没有。
    • @rmaddy 您好,我使用了您提供的代码,但是当我单击按钮时应用程序崩溃了。
    • 错误信息是什么?这段代码在哪个类中?它继承自什么?
    【解决方案2】:

    让我们在做任何事情之前检查+authorizationStatus(类PHPhotoLibrary)的值。如果状态为PHAuthorizationStatus.notDetermined,您也可以使用方法+requestAuthorization 请求访问照片库

    更多信息:PHPhotoLibrary authorizationStatusPHPhotoLibrary requestAuthorization

    【讨论】:

      【解决方案3】:

      一般:

      • 图像写入完成时不需要通知您(在许多情况下这没有用),因此您对两个参数都使用nil
      • 或者你真的想在图片文件写入相册(或者写入错误结束)时得到通知,这种情况下,你一般实现回调(=完成时调用的方法)在您调用 UIImageWriteToSavedPhotosAlbum 函数的同一类中,因此 completionTarget 通常为 self

      正如文档所述,completionSelector 是一个选择器,表示具有文档中描述的签名的方法,因此它必须具有如下签名:

      - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo: (void *) contextInfo;
      

      它不必有这个确切的名称,但它必须使用相同的签名,即采用 3 个参数(第一个是 UIImage,第二个是 NSError,第三个是 void* 类型) 并且什么也不返回 (void)。


      示例

      例如,您可以声明并实现一个方法,您可以像这样调用任何方法:

      - (void)thisImage:(UIImage *)image hasBeenSavedInPhotoAlbumWithError:(NSError *)error usingContextInfo:(void*)ctxInfo {
          if (error) {
              // Do anything needed to handle the error or display it to the user
          } else {
              // .... do anything you want here to handle
              // .... when the image has been saved in the photo album
          }
      }
      

      当你调用UIImageWriteToSavedPhotosAlbum 时,你会像这样使用它:

      UIImageWriteToSavedPhotosAlbum(theImage,
         self, // send the message to 'self' when calling the callback
         @selector(thisImage:hasBeenSavedInPhotoAlbumWithError:usingContextInfo:), // the selector to tell the method to call on completion
         NULL); // you generally won't need a contextInfo here
      

      注意@selector(...) 语法中的多个“:”。冒号是方法名称的一部分,所以不要忘记在@selector 中添加这些':'(当你写这行代码的时候)!

      【讨论】:

      • 问题在于 Swift,而不是 Objective-C。最好以正确的语言发布答案。
      猜你喜欢
      • 1970-01-01
      • 2018-12-28
      • 2022-10-24
      • 2015-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      • 2016-01-20
      相关资源
      最近更新 更多