因此,我有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秒后)运行一些东西。我的视图控制器不是导航控制器的一部分,因此this post没有帮助。我还希望我的代码在目标视图控制器中,但是this post源视图控制器中具有它,因此也无济于事。

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

最佳答案

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

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

  • Presentation控制器;
  • 用于呈现模态的动画控制器;和
  • 用于消除模态
  • 的动画控制器

    例如,目标视图控制器将指定它将执行自定义过渡:
    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,然后您可以执行标准的模式演示(通过 present show 或仅通过segue进行),并且将自定义过渡动画,并在动画播放时调用目标的viewDidAppear已经完成了。

    关于ios - swift 4-segue动画完成后,如何在目标 View Controller 中运行代码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49968080/

    10-12 14:44
    查看更多