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

Posted

技术标签:

【中文标题】从 UINavigationController 中删除动画推送展开?【英文标题】:Removing Animation From UINavigationController Pushed Unwind? 【发布时间】:2021-08-12 20:11:18 【问题描述】:

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

在附加的 Playground 中,为 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())

【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

谢谢!这可能是我需要的。我明天试试。【参考方案2】:

我正在检查@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())

【讨论】:

不错!该 API(以及交互式变体和 UIPresentationController)是一个真正的兔子洞,可以很好地满足您的需求:)

以上是关于从 UINavigationController 中删除动画推送展开?的主要内容,如果未能解决你的问题,请参考以下文章

从 UINavigationController 切换到 UISplitviewController

从UINavigationController中控制UINavigationItem内容

从 UINavigationController 设置 UITabBarItem 标题?

如何从 UINavigationController 隐藏 UINavigationBar?

UINavigationController 内的 UIPageController 从顶部偏移?

从 UiviewController 切换到 UiNavigationController