UINavigationControllerDelegate 方法,在 ios 8 中使用导航控制器自定义转换
UINavigationControllerDelegate methods, custom transitioning using navigation controller in ios 8
我正在尝试在弹出或推送我的导航控制器时创建一个自定义 t运行sition。我创建了一个符合 UINavigationControllerDelegate 的 t运行sitionManager class。我已经创建了这个 t运行sitionManager 的对象,并将它作为 t运行sitioningDelegate 添加到我的 navigationController。
推送动画运行得很好,但是当我尝试返回上一个时 viewController 我只看到黑屏。
我 运行 通过许多其他帖子使其工作并尝试了手头的一切,但当我弹出时它仍然没有显示以前的 ViewController。
t运行sitionManager 的代码在这里:
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
}
}
UINavigationController 维护对其委托的弱引用。如果没有强引用,则 UINavigationControllerDelegate 对象在转换完成后被释放。
您可以在故事板编辑器中设置委托对象。通过将对象从调色板拖动到导航控制器场景中的 First Responder 和 Exit 图标之间来添加一个对象。将其 class 设置为您的委托对象的 class 。确保该模块是您当前的应用程序模块。然后 control-drag 从导航控制器图标到对象图标,然后从弹出菜单中选择 "delegate"。
这似乎维护了对委托对象的强引用。然后委托对象将可用于调用展开转换。您不需要自己创建对象或设置委托引用。
我在 Scott James Remnant 的博客 post 中发现了这种技术。
Scott James Remnant - Custom iOS Segues, Transitions, and Animations - The Right Way
我正在尝试在弹出或推送我的导航控制器时创建一个自定义 t运行sition。我创建了一个符合 UINavigationControllerDelegate 的 t运行sitionManager class。我已经创建了这个 t运行sitionManager 的对象,并将它作为 t运行sitioningDelegate 添加到我的 navigationController。
推送动画运行得很好,但是当我尝试返回上一个时 viewController 我只看到黑屏。
我 运行 通过许多其他帖子使其工作并尝试了手头的一切,但当我弹出时它仍然没有显示以前的 ViewController。
t运行sitionManager 的代码在这里:
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
}
}
UINavigationController 维护对其委托的弱引用。如果没有强引用,则 UINavigationControllerDelegate 对象在转换完成后被释放。
您可以在故事板编辑器中设置委托对象。通过将对象从调色板拖动到导航控制器场景中的 First Responder 和 Exit 图标之间来添加一个对象。将其 class 设置为您的委托对象的 class 。确保该模块是您当前的应用程序模块。然后 control-drag 从导航控制器图标到对象图标,然后从弹出菜单中选择 "delegate"。
这似乎维护了对委托对象的强引用。然后委托对象将可用于调用展开转换。您不需要自己创建对象或设置委托引用。
我在 Scott James Remnant 的博客 post 中发现了这种技术。
Scott James Remnant - Custom iOS Segues, Transitions, and Animations - The Right Way