ios - UIView.animate 未在 PHPhotoLibrary.shared().performChanges 中执行

标签 ios swift uiviewanimation

我一整天都在处理以下代码,但根本找不到问题所在。我想保存视频并在完成后使某些按钮或微调器(消失)出现。所有按钮都在 viewDidLoad 中设置,可以说是存在的(它们是可选的,因此也是可选的链接)。我的问题是 if 子句中的动画永远不会执行。只是有时候,如果我在每一行代码之前放置断点,它就会起作用,这真的让我感到奇怪(顺便说一句:断点并不表示任何异常)。此外,如果我用 else (if success2 == false) 的代码替换 if success2 == true 的代码,它有效(弹出警报后)。我几乎四次检查了我的代码,但就是找不到我做错了什么。有没有人知道问题可能是什么以及如何解决?

抱歉有这么大的代码块:

PHPhotoLibrary.shared().performChanges({
    if let assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url) {
        let assetCollectionChangeRequest = PHAssetCollectionChangeRequest(for: albumAssetCollection)
        let enumeration: NSArray = [assetChangeRequest.placeholderForCreatedAsset!]
        assetCollectionChangeRequest?.addAssets(enumeration)
    }
}, completionHandler: { (success2: Bool, error2: Error?) in
    if success2 == true {
        // prompt that the video has been saved
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
            if let checkButton = self.checkButton, let saveSpinner = self.saveSpinner, let resetButton = self.resetButton {
                saveSpinner.alpha = 0
                checkButton.alpha = 1
                resetButton.alpha = 1
            }
        }) { (completed: Bool) in
            if completed == true {
                if let saveSpinner = self.saveSpinner {
                    saveSpinner.stopAnimating()
                    self.timeLimitReached = false
                    self.changeClipsCount()
                }
                UIView.animate(withDuration: 0.5, delay: 3, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                    if let checkButton = self.checkButton, let saveButton = self.saveButton {
                        checkButton.alpha = 0
                        saveButton.alpha = 1
                    }
                }) { (completed: Bool) in }
            }
        }
    } else {
        // prompt that the video has not been saved
        let alertController = UIAlertController(title: "Something failed!", message: "The video could not be saved.", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        alertController.addAction(okAction)
        self.present(alertController, animated: true, completion: {
            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                if let saveButton = self.saveButton, let saveSpinner = self.saveSpinner {
                    saveButton.alpha = 1
                    saveSpinner.alpha = 0
                }
            }) { (completed: Bool) in
                if let saveSpinner = self.saveSpinner {
                    saveSpinner.stopAnimating()
                    self.timeLimitReached = false
                }
            }
        })
    }
})

最佳答案

我会将我的评论作为答案发布,并提供一些更好的解释。

要使 UIView 动画正常工作,它们必须在主线程上使用(就像所有其他 UIKit 东西一样!)。

From the documentation对于 PHPhotoLibrary,Apple 声明:

Photos executes both the change block and the completion handler block on an arbitrary serial queue. To update your app’s UI as a result of a change, dispatch that work to the main queue.

这意味着您应该期望处理来自 Apple 的响应,就像它来自主线程以外的其他地方一样。因此,一个简单的解决方法是调用:

DispatchQueue.main.async {} 并将其包裹在您想要执行 UIKit 操作的代码周围。

Apple 不在主线程上工作的原因是因为他们正在做的工作可能很重要,而且它会占用主线程,这会使您的 UI 缓慢且无响应。

我还建议对您的代码进行一些小调整,以使其更易于阅读。在完成处理程序中,我会将代码提取到一个函数中,然后您所要做的就是将该函数调用包装在 DispatchQueue.main.async {} 调用中,而不是整个代码块你想要动画。

另外不要忘记使用 Swift 最好的语言特性之一:optional chaining .这意味着你不必在尝试使用它之前检查它是否存在,如果它不存在它就会退出。所以你可以安全地做这样的事情:

checkButton?.alpha = 1

关于ios - UIView.animate 未在 PHPhotoLibrary.shared().performChanges 中执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45120208/

相关文章:

javascript - 处理不缓存音频的 IOS Web 浏览器

ios - Cocoa Pods Shell 脚本调用错误

ios - layoutSubviews 中的动画?

objective-c - 无法解释的崩溃 iOS

快速/解析: error when setting Parse data to labels

swift - 删除数据和缓存 wkwebview swift 4

ios - 将 AVAudioPlayer 声音保留在内存中

iOS,在 slider 值 n 处触发一次 UIView 动画?

iphone - IOS UiView动画在ios 5和ios 6设备上产生不同的效果

ios - Venmo touch Braintree 支付 - 编译错误 : Undefined symbols for architecture i386: "_OBJC_CLASS_$_VTClient"