繁体   English   中英

迅捷4-segue动画完成后,如何在目标视图控制器中运行代码?

[英]swift 4 - how do I run code in the destination view controller AFTER the segue animation is finished?

所以我有2个视图控制器,我想从视图控制器1到带有自定义动画的视图控制器2 这是我的自定义动画的代码:

let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
self.view.window?.layer.add(transition, forKey: nil)

在调用performSegue()之前,我先运行了它,然后它起作用了。 但是我想做的是在视图控制器2的代码中,我想在segue动画完成后(在0.5秒后)运行某些内容。 我的视图控制器不是导航控制器的一部分,因此本文无济于事。 我也希望我的代码在目标视图控制器中 ,但是本文源视图控制器中有它,因此也无济于事。

我已经尝试测试viewDidLoad()viewDidAppear() ,但是它们都在滑动动画完成之前运行。 请帮忙,谢谢!

当正确设置过渡的动画时,动画完成后将调用viewDidAppear 有关在两个视图控制器之间自定义过渡的正确方法的说明,请参见《 iOS的View Controller编程指南》中的“ 自定义过渡动画

如该指南所述,当您要自定义模式过渡时,应指定modalPresentationStyle.custom ,然后指定transitioningDelegate来提供:

  • 演示控制器;
  • 动画控制器,用于呈现模态;
  • 动画控制器,用于消除模态

例如,目标视图控制器将指定它将执行自定义转换:

class ViewController: UIViewController {

    // if storyboards, override `init(coder:)`; if NIBs or programmatically 
    // created view controllers, override the appropriate `init` method.

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        transitioningDelegate = self
        modalPresentationStyle = .custom
    }

    ...

}

并且,在其UIViewControllerTransitioningDelegate ,它出售了表示控制器和动画控制器:

extension ViewController: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return TransitionAnimator(operation: .present)
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return TransitionAnimator(operation: .dismiss)
    }

    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        return PresentationController(presentedViewController: presented, presenting: presenting)
    }
}

演示控制器的全部工作是指定完成过渡后应从视图层次结构中删除演示者的视图(这是经验法则,除非演示视图是半透明的或不覆盖整个屏幕):

class PresentationController: UIPresentationController {
    override var shouldRemovePresentersView: Bool { return true }
}

动画师指定动画的持续时间和特定细节:

class TransitionAnimator: NSObject {

    enum TransitionOperation {
        case present
        case dismiss
    }

    private let operation: TransitionOperation

    init(operation: TransitionOperation) {
        self.operation = operation
        super.init()
    }
}

extension TransitionAnimator: UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 2.0
    }

    func animateTransition(using context: UIViewControllerContextTransitioning) {
        let toVC = context.viewController(forKey: .to)!
        let fromVC = context.viewController(forKey: .from)!
        let container = context.containerView

        let frame = fromVC.view.frame
        let rightFrame = CGRect(origin: CGPoint(x: frame.origin.x + frame.width, y: frame.origin.y), size: frame.size)
        let leftFrame = CGRect(origin: CGPoint(x: frame.origin.x - frame.width, y: frame.origin.y), size: frame.size)

        switch operation {
        case .present:
            toVC.view.frame = rightFrame
            container.addSubview(toVC.view)
            UIView.animate(withDuration: transitionDuration(using: context), animations: {
                toVC.view.frame = frame
                fromVC.view.frame = leftFrame
            }, completion: { finished in
                fromVC.view.frame = frame
                context.completeTransition(!context.transitionWasCancelled)
            })

        case .dismiss:
            toVC.view.frame = leftFrame
            container.addSubview(toVC.view)
            UIView.animate(withDuration: transitionDuration(using: context), animations: {
                toVC.view.frame = frame
                fromVC.view.frame = rightFrame
            }, completion: { finished in
                fromVC.view.frame = frame
                context.completeTransition(!context.transitionWasCancelled)
            })
        }
    }
}

显然,可以执行所需的任何动画,但希望您能掌握基本的想法。 最重要的是,目标视图控制器应指定其transitioningDelegate ,然后您可以进行标准的模式演示(通过presentshow或仅是segue),并且将自定义过渡动画,并在动画播放时调用目标的viewDidAppear已经完成了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM