Какие обработчики завершения я должен написать? - PullRequest
0 голосов
/ 25 мая 2018

Только что узнав о том, как создавать обработчики завершения, я в принципе понимаю их, но я не знаю, как реализовать идеи на практике для достижения того, что мне нужно.

У меня есть следующий общий коди структура раскадровки: sessionVC (UIViewController) и его UIView содержат контейнерное представление с переходом на embed to animationVC (также UIViewController) и его SKView.

Из sessionVC я хочу запустить серию анимаций в animationVC SKView,Я хотел бы подготовить каждую анимацию как можно скорее (например, пока каждая предыдущая анимация еще работает), и я бы хотел, чтобы каждая анимация ожидала завершения последней, прежде чем она начнется.См. Код ниже.

Мой вопрос состоит в том, что я должен поставить вместо ??? в моем коде для достижения желаемых эффектов (упомянутых выше, а также после каждого ***).в комментариях к коду)?

// 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
    }
}

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Хочешь что-нибудь подобное?

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
})
0 голосов
/ 25 мая 2018

Следуя обычным соглашениям, вы объявите функции с несколько иной формулировкой:

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()
}

И если вы предпочитаете иметь дополнительные обработчики завершения, т. Е. Те, которые могут быть нулевыми, измените функцию следующим образом:

func prepareContent(_ content: Content, completionHandler: (() -> Void)?) {
    // ...
    completionHandler?()
}
0 голосов
/ 25 мая 2018

Это должно выглядеть примерно так:

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
})

Вы можете адаптировать его к вашим потребностям, добавляя больше или меньше выходных данных, если это необходимо, журналы ошибоки т. д.

...