从 UINavigationController 中删除动画推送展开?

Removing Animation From UINavigationController Pushed Unwind?

我有一个从一个视图控制器到另一个视图控制器的简单推送转场。我希望两个 segues(原始和展开都没有动画)。

在附带的游乐场中,为segue指定false确实删除了PUSH动画,但没有删除UNWIND动画。

有没有办法去除 UNWIND segue 中的隐式动画?

import UIKit
import PlaygroundSupport

class SourceViewController : UIViewController {
    @objc func goDestination(_: Any) {
        navigationController?.pushViewController(DestinationViewController(), animated: false)
    }
    
    override func loadView() {
        view = UIView()
        navigationItem.title = "SOURCE"
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(goDestination(_:)))
    }
}

class DestinationViewController : UIViewController {
    override func loadView() {
        view = UIView()
        view.backgroundColor = .yellow
        navigationItem.title = "DESTINATION"
    }
}

PlaygroundPage.current.liveView = UINavigationController(rootViewController: SourceViewController())

这些动画完全可以从 UINavigationControllerDelegate 自定义,查看第一个“支持自定义过渡动画”方法

https://developer.apple.com/documentation/uikit/uinavigationcontrollerdelegate

这里有一些细节https://www.youtube.com/watch?v=jWckfDNUJVY 在 23 分钟。

我正在检查@glotcha 的回答。它让我找到了 this Medium post,这让我找到了这个解决方案(我真的想要一个淡入淡出的过渡):

import UIKit
import PlaygroundSupport

class TransitioningAnimatorInOut: NSObject, UIViewControllerAnimatedTransitioning {
    var presenting: Bool = false
    
    func transitionDuration(using: UIViewControllerContextTransitioning?) -> TimeInterval { 0.75 }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromView = transitionContext.view(forKey: .from),
              let toView = transitionContext.view(forKey: .to) else { return }

        let container = transitionContext.containerView
        
        if presenting {
            container.addSubview(toView)
            toView.alpha = 0.0
        } else {
            container.insertSubview(toView, belowSubview: fromView)
        }
        
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
        if self.presenting {
                toView.alpha = 1.0
            } else {
                fromView.alpha = 0.0
            }
        }) { _ in
            let success = !transitionContext.transitionWasCancelled
            if !success {
                toView.removeFromSuperview()
            }
            transitionContext.completeTransition(success)
        }
    }
    
    init(presenting inPresenting: Bool) { presenting = inPresenting }
}

extension UINavigationController: UINavigationControllerDelegate {
    public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        if operation == .push {
            return TransitioningAnimatorInOut(presenting: true)
        } else {
            return TransitioningAnimatorInOut(presenting: false)
        }
    }
}

class SourceViewController : UIViewController {
    @objc func goDestination(_: Any) {
        navigationController?.pushViewController(DestinationViewController(), animated: true)
    }
    
    override func loadView() {
        view = UIView()
        view?.backgroundColor = .yellow
        navigationItem.title = "SOURCE"
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(goDestination(_:)))
    }
}

class DestinationViewController : UIViewController {
    override func loadView() {
        view = UIView()
        view?.backgroundColor = .red
        navigationItem.title = "DESTINATION"
    }
}

PlaygroundPage.current.liveView = UINavigationController(rootViewController: SourceViewController())