我应该写什么完成处理程序?
What Completion Handlers Should I Write?
刚刚学习了如何创建completion handlers,大体上理解了它们,但我不知道如何将这些想法付诸实践来完成我需要的东西。
我有以下通用代码和故事板结构:sessionVC(一个 UIViewController)及其 UIView 包含一个容器视图,其中嵌入了到 animationVC(也是一个 UIViewController)及其 SKView 的转场。
我想从sessionVC中运行在animationVC的SKView中做一系列的动画。我想尽快准备每个动画(例如,当每个先前的动画仍在 运行ning 时),并且我希望每个动画在开始之前等待最后一个动画完成。请参阅下面的代码。
我的问题是,我应该用什么来代替代码中的 ???s 来实现我想要的效果(如上所述,以及代码注释中的每个 *** 之后)?
// 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
}
}
它应该看起来像:
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
})
您可以根据需要调整它,根据需要添加或多或少的输出、错误日志等。
你想要这样的东西吗?
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
})
按照通常的约定,您将使用稍微不同的措辞声明函数:
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()
}
如果您更喜欢可选的完成处理程序,我。 e.可以为nil的,把函数改成这样:
func prepareContent(_ content: Content, completionHandler: (() -> Void)?) {
// ...
completionHandler?()
}
刚刚学习了如何创建completion handlers,大体上理解了它们,但我不知道如何将这些想法付诸实践来完成我需要的东西。
我有以下通用代码和故事板结构:sessionVC(一个 UIViewController)及其 UIView 包含一个容器视图,其中嵌入了到 animationVC(也是一个 UIViewController)及其 SKView 的转场。
我想从sessionVC中运行在animationVC的SKView中做一系列的动画。我想尽快准备每个动画(例如,当每个先前的动画仍在 运行ning 时),并且我希望每个动画在开始之前等待最后一个动画完成。请参阅下面的代码。
我的问题是,我应该用什么来代替代码中的 ???s 来实现我想要的效果(如上所述,以及代码注释中的每个 *** 之后)?
// 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
}
}
它应该看起来像:
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
})
您可以根据需要调整它,根据需要添加或多或少的输出、错误日志等。
你想要这样的东西吗?
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
})
按照通常的约定,您将使用稍微不同的措辞声明函数:
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()
}
如果您更喜欢可选的完成处理程序,我。 e.可以为nil的,把函数改成这样:
func prepareContent(_ content: Content, completionHandler: (() -> Void)?) {
// ...
completionHandler?()
}