"Saved photo" 在用户允许访问照片库之前弹出警告?

"Saved photo" alert popping up before the user allows permissions to photo library?

当用户点击按钮时,它会在询问用户许可之前立即触发 "Photo has been saved" 警报。如果用户单击否,则照片不会保存,但仍会显示警告。是否有一个 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)


}

让我们在做任何事情之前检查一下 +authorizationStatus (class PHPhotoLibrary) 的值。如果状态为 PHAuthorizationStatus.notDetermined

,您还可以使用方法 +requestAuthorization 请求访问照片库

更多信息:PHPhotoLibrary authorizationStatus, PHPhotoLibrary requestAuthorization

您太早显示警报控制器了。对 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)
    }
}

一般:

  • 要么不需要在写完图片的时候通知你(很多情况下是没用的),所以两个参数都用nil
  • 或者你很想在图片文件写入相册(或者写入错误)时得到通知,这种情况下一般会实现回调(=调用方法completion) 在你调用 UIImageWriteToSavedPhotosAlbum 函数的同一个 class 中,所以 completionTarget 通常是 self

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

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

它不必具有这个确切的名称,但它必须使用相同的签名,即采用 3 个参数(第一个是 UIImage,第二个是 NSError,第三个void* 类型)和 return 无(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 中添加这些 ':'(事件是 trainling 一个),当你写这行的时候!