swift 4 - 如何在segue动画结束后在目标视图控制器中运行代码?

时间:2018-04-22 16:14:08

标签: ios swift uistoryboardsegue

所以我有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源视图控制器中包含它,因此这也无济于事。< / p>

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

1 个答案:

答案 0 :(得分:5)

正确设置过渡动画后,动画完成后将调用viewDidAppear。有关在两个视图控制器之间自定义转换的正确方法的说明,请参阅 View Controller Programming for iOS 中的Customizing Transition Animations

正如该指南所述,当您想要自定义模态转换时,您应指定.custom 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 } ... } ,然后指定将提供的modalPresentationStyle

  • 演示控制器;
  • 用于呈现模态的动画控制器;和
  • 用于解除模态的动画控制器

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

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

显然,做你想做的任何动画,但希望你得到基本的想法。底线,目标视图控制器应指定其viewDidAppear,然后您可以只进行标准模式演示(通过transitioningDelegatepresent或只是一个segue),您的过渡动画将自定义,动画完成后将调用目的地List<Map<String,String>> MyData = null; ADAhere = new SimpleAdapter(getActivity(), MyData,R.layout.list_products, fromwhere, viewswhere);