我应该写啥完成处理程序?
Posted
技术标签:
【中文标题】我应该写啥完成处理程序?【英文标题】:What Completion Handlers Should I Write?我应该写什么完成处理程序? 【发布时间】:2018-05-25 13:56:15 【问题描述】:刚刚了解了如何创建完成处理程序,我在原则上理解它们,但我不知道如何将这些想法付诸实践以完成我所需要的。
我有以下通用代码和故事板结构:sessionVC(一个 UIViewController)及其 UIView 拥有一个容器视图,其中包含一个嵌入到 animationVC(也是 UIViewController)及其 SKView 的 segue。
从 sessionVC 我想在 animationVC 的 SKView 中运行一系列动画。我希望尽快准备好每个动画(例如,在每个之前的动画仍在运行时),并且我希望每个动画在开始之前等待最后一个动画完成。请参阅下面的代码。
我的问题是,我应该在我的代码中放置什么来代替 ???s 来完成我想要的效果(上面提到,以及在代码 cmets 中的每个 *** 之后)?
// TO DELEGATE ANIMATION TO animationVC
protocol AnimateContentDelegate: AnyObject
prepareContent(_ Content, contentWasPrepared: ???)
animateContent(animationDidComplete: ???)
playAnimation()
pauseAnimation()
// CONTROL THE OVERALL SESSION
class sessionVC: UIViewController
// INITIALIZE contentArray
weak var delegate: AnimateContentDelegate?
override func viewDidLoad
super.viewDidLoad()
delegate = self.childViewControllers[0] as? AnimateContentDelegate
runSession(contentArray)
func runSession(_ contentArray)
for content in contentArray
delegate?.prepareContent(content, contentWasPrepared: ???)
// ***DON’T START THE NEXT ANIMATION UNTIL contentWasPrepared
// DO CONTINUE THE CURRENT ANIMATION, AND ALLOW INTERACTIONS
delegate?.animateContent(animationDidComplete: ???)
// ***DON’T START THE NEXT ANIMATION UNTIL animationDidComplete
// DO CONTINUE THE CURRENT ANIMATION, AND ALLOW INTERACTIONS
@IBAction func playOrPause(_ sender: UILongPressGestureRecognizer)
if sender == .possible || sender.state == .ended
delegate?.playAnimation()
else if sender.state == .began
delegate?.pauseAnimation()
// PREPARE AND ANIMATE CURRENT CONTENT
class animationVC: UIViewController, AnimateContentDelegate
// SET UP SKVIEW
func prepareContent(_ content: Content, prepCompleteHandler: ???)
// PREPARE THE CONTENT
// ***REPORT WHEN IT IS FINISHED
func animateContent(animationCompleteHandler: ???)
// ANIMATE THE CONTENT
// ***REPORT IF IT RAN TO COMPLETION
func playAnimation()
skView?.scene?.isPaused = false
func pauseAnimation()
skView?.scene?.isPaused = true
【问题讨论】:
【参考方案1】:按照通常的约定,您可以用稍微不同的措辞声明函数:
prepareContent(_ Content, completionHandler: () -> Void )
animateContent(completionHandler: () -> Void )
然后,在 SET UP SKVIEW 下方,您可以像这样调用委托函数:
delegate?.prepareContent(content, completionHandler:
self.delegate.animateContent(completionHandler:
// do whatever needs to be done upon completion
)
)
(您也可以使用尾随闭包语法。) 通过像这样嵌套委托调用,您可以确保动画仅在准备完成后执行。
函数体如下所示:
func prepareContent(_ content: Content, completionHandler: (() -> Void))
// ...
completionHandler()
func animateContent(completionHandler: (() -> Void))
// ...
completionHandler()
如果您更喜欢使用可选的完成处理程序,i。 e.那些可以为零的,改变这样的功能:
func prepareContent(_ content: Content, completionHandler: (() -> Void)?)
// ...
completionHandler?()
【讨论】:
感谢@Tom E 的指导。将 animateContent 函数嵌套在一个块中作为 prepareContent 的完成处理程序是最大的帮助,但是您对我的代码的其他修复使一切变得容易理解。 @Optimalist:很高兴我能帮上忙!【参考方案2】:它应该看起来像:
func prepareContent(_ content: Content, completionHandler: @escaping (Bool, Any?) -> Void) -> Void
var finished : Bool = false
var output : Any? = nil
// prepare the content
// possibly update the output
//when ready :
finished = true
completionHandler(finished, output)
那你就用它吧:
prepareContent(content: content, completionHandler: (f, o) in
if f
if o != nil
//do something
//else handle error
//else handle error
)
您可以根据需要调整它,根据需要添加更多或更少的输出、错误日志等。
【讨论】:
动画方法或使用完成处理程序的任何方法也是如此【参考方案3】:你想要这样的东西吗?
protocol AnimateContentDelegate: AnyObject
func prepareContent(content : Content, contentWasPrepared: ((Bool) -> Void)?)
func animateContent(animationDidComplete: ((Bool) -> Void)?)
func playAnimation()
func pauseAnimation()
class YourObject : AnimateContentDelegate
func prepareContent(content: Content, contentWasPrepared: ((Bool) -> Void)?)
// prepare content
func animateContent(animationDidComplete: ((Bool) -> Void)?)
// animate content
func playAnimation()
func pauseAnimation()
这样使用:
let yourObject = YourObject()
yourObject.animateContent(animationDidComplete: finished in
// animation did complete
)
【讨论】:
以上是关于我应该写啥完成处理程序?的主要内容,如果未能解决你的问题,请参考以下文章
我应该在这里使用完成处理程序吗?如果是这样,如何最好地做到这一点?
我应该在 tableView(_:cellForRowAtIndexPath:) 方法中为自定义单元格写啥?