Completion handler for UINavigationController “pushViewController:animated”?

前端 未结 9 1094
礼貌的吻别
礼貌的吻别 2020-11-30 18:08

I\'m about creating an app using a UINavigationController to present the next view controllers. With iOS5 there´s a new method to presenting UIViewControl

9条回答
  •  情书的邮戳
    2020-11-30 18:26

    iOS 7+ Swift

    Swift 4:

    // 2018.10.30 par:
    //   I've updated this answer with an asynchronous dispatch to the main queue
    //   when we're called without animation. This really should have been in the
    //   previous solutions I gave but I forgot to add it.
    extension UINavigationController {
        public func pushViewController(
            _ viewController: UIViewController,
            animated: Bool,
            completion: @escaping () -> Void)
        {
            pushViewController(viewController, animated: animated)
    
            guard animated, let coordinator = transitionCoordinator else {
                DispatchQueue.main.async { completion() }
                return
            }
    
            coordinator.animate(alongsideTransition: nil) { _ in completion() }
        }
    
        func popViewController(
            animated: Bool,
            completion: @escaping () -> Void)
        {
            popViewController(animated: animated)
    
            guard animated, let coordinator = transitionCoordinator else {
                DispatchQueue.main.async { completion() }
                return
            }
    
            coordinator.animate(alongsideTransition: nil) { _ in completion() }
        }
    }
    

    EDIT: I've added a Swift 3 version of my original answer. In this version I've removed the example co-animation shown in the Swift 2 version as it seems to have confused a lot of people.

    Swift 3:

    import UIKit
    
    // Swift 3 version, no co-animation (alongsideTransition parameter is nil)
    extension UINavigationController {
        public func pushViewController(
            _ viewController: UIViewController,
            animated: Bool,
            completion: @escaping (Void) -> Void)
        {
            pushViewController(viewController, animated: animated)
    
            guard animated, let coordinator = transitionCoordinator else {
                completion()
                return
            }
    
            coordinator.animate(alongsideTransition: nil) { _ in completion() }
        }
    }
    

    Swift 2:

    import UIKit
    
    // Swift 2 Version, shows example co-animation (status bar update)
    extension UINavigationController {
        public func pushViewController(
            viewController: UIViewController,
            animated: Bool,
            completion: Void -> Void)
        {
            pushViewController(viewController, animated: animated)
    
            guard animated, let coordinator = transitionCoordinator() else {
                completion()
                return
            }
    
            coordinator.animateAlongsideTransition(
                // pass nil here or do something animated if you'd like, e.g.:
                { context in
                    viewController.setNeedsStatusBarAppearanceUpdate()
                },
                completion: { context in
                    completion()
                }
            )
        }
    }
    

提交回复
热议问题