我现在一整天都在处理以下代码,根本无法找到问题。我想保存视频,完成后会出现某些按钮或旋转器(dis-)。所有按钮都在viewDidLoad
中设置,因此可以说存在(它们是可选项,因此也是可选链接)。我的问题是if
子句中的动画永远不会被执行。有时候,如果我在每行代码之前放置断点,那么它确实让我感到奇怪(顺便说一句:断点并不表示任何异常)。此外,如果我将if success2 == true
的代码替换为else
(if success2 == false
)的代码,则可以正常工作(在弹出警报后)。我差不多四次检查我的代码,只是找不到我做错了什么。有谁知道可能是什么问题以及如何解决?
对于巨大的代码块抱歉:
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
}
}
})
}
})
答案 0 :(得分:2)
我将发表评论作为答案,并提供一些更好的解释。
要使UIView
动画起作用,必须在主线程上使用它们(就像所有其他UIKit一样!)。
PHPhotoLibrary
,From the documentation,Apple表示:
Photos会在任意串行队列上执行更改块和完成处理程序块。要根据更改更新应用的UI,请将该工作分配到主队列。
这意味着您应该期望处理来自Apple的响应,就好像它来自主线程之外的某个地方。因此,一个简单的解决方法是致电:
DispatchQueue.main.async {}
并将代码包围在您想要执行UIKit的代码中。
Apple不在主线程上工作的原因是因为他们正在做的工作可能很重要,并且会占用主线程,这会使你的UI缓慢且无响应。 / p>
我还建议您对代码进行一些小调整,以便更容易阅读。在完成处理程序中,我将代码提取到一个函数中,然后你所要做的就是在DispatchQueue.main.async {}
调用中包装该函数调用,而不是你想要动画的整个代码块。
另外,请不要忘记使用Swift最好的语言功能之一:optional chaining。这意味着在尝试使用它之前你不必检查是否存在某些东西,如果它不存在它就会拯救它。所以你可以安全地做这样的事情:
checkButton?.alpha = 1