因此,我有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
,该提供:
例如,目标视图控制器将指定它将执行自定义过渡:
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/