【问题标题】:UINavigationControllerDelegate methods, custom transitioning using navigation controller in ios 8UINavigationControllerDelegate 方法,在 ios 8 中使用导航控制器进行自定义转换
【发布时间】:2024-01-12 03:39:02
【问题描述】:

我正在尝试在弹出或推送我的导航控制器时创建自定义转换。我创建了一个符合 UINavigationControllerDelegate 的 transitionManager 类。我已经创建了这个 transitionManager 的对象并将它作为一个 transitioningDelegate 添加到我的 navigationController。

推送动画运行良好,但是当我尝试弹回之前的 viewController 时,我只看到黑屏。

我浏览了许多其他帖子以使其正常工作并尝试了手头的所有方法,但当我弹出时它仍然不显示以前的 ViewController。

transitionManager 的代码在这里:

import UIKit

class BRTransitionManager: NSObject, UINavigationControllerDelegate, UIViewControllerAnimatedTransitioning {

    private var presenting = true

    func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {

        if  operation == UINavigationControllerOperation.Push{
            self.presenting = true
        } else if operation == UINavigationControllerOperation.Pop{
            self.presenting = false
        }

        return self
    }

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        let container = transitionContext.containerView()
        let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
        let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!

        // set up from 2D transforms that we'll use in the animation
        let offScreenRight = CGAffineTransformMakeTranslation(container.frame.width, 0)
        let offScreenLeft = CGAffineTransformMakeTranslation(-container.frame.width, 0)

        // prepare the toView for the animation
        if (self.presenting == true) {
            // add the both views to our view controller
            container.addSubview(toView)
            // container.addSubview(fromView)

            toView.transform = offScreenRight
        } else {
            toView.transform = offScreenLeft
        }

        let duration = self.transitionDuration(transitionContext)
        UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: nil, animations: {

            if (self.presenting == true) {
                fromView.transform = offScreenLeft
            } else {
                fromView.transform = offScreenRight
            }

            toView.transform = CGAffineTransformIdentity

        }, completion: { finished in

            transitionContext.completeTransition(true)
        })
    }

    func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
        return 0.8
    }   
}

【问题讨论】:

    标签: ios swift uinavigationcontroller custom-transition


    【解决方案1】:

    UINavigationController 维护对其委托的弱引用。如果没有强引用,则 UINavigationControllerDelegate 对象在转换完成后被释放。

    您可以在 Storyboard Editor 中设置委托对象。通过将对象从调色板拖到 Navigation Controller 场景中,在 First Responder 和 Exit 图标之间添加一个对象。将其类设置为您的委托对象的类。确保该模块是您当前的应用程序模块。然后从导航控制器图标按住控件拖动到对象图标,然后从弹出菜单中选择“委托”。

    这似乎保持了对委托对象的强引用。然后,委托对象将可用于调用展开转换。您无需自己创建对象或设置委托引用。

    我在 Scott James Remnant 的博客文章中发现了这种技术。

    Scott James Remnant - Custom iOS Segues, Transitions, and Animations - The Right Way

    【讨论】:

    • Scott 的自定义 iOS segues 文章的链接已失效,但您可以在 Wayback 机器上找到原件:web.archive.org/web/20160318041625/http://netsplit.com/…>。非常好。