自定义 Viewcontroller 过渡未正确调整大小
Custom Viewcontroller transition doesn't resize properly
我在我的应用程序中为导航控制器自定义了 Viewcontroller 转换。执行转换时,它没有正确调整子 viewcontroller 内容的大小。默认过渡会调整它的大小。
I have added an example project on Github to demonstrate the issue.
内嵌的VCNavigation Controller
import UIKit
class PopoverVCViewController: UIViewController, UIViewControllerTransitioningDelegate, UINavigationControllerDelegate {
let animator = Animator()
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
animator.reverse = operation == .Pop
return animator
}
}
动画师
class Animator: NSObject, UIViewControllerAnimatedTransitioning {
var reverse: Bool = false
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
// get reference to our fromView, toView and the container view that we should perform the transition in
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)
// start the toView to the right of the screen
if (self.reverse == false) {
toView.transform = offScreenRight
}
else {
toView.transform = offScreenLeft
}
// add the both views to our view controller
container.addSubview(toView)
container.addSubview(fromView)
// get the duration of the animation
// DON'T just type '0.5s' -- the reason why won't make sense until the next post
// but for now it's important to just follow this approach
let duration = self.transitionDuration(transitionContext)
// perform the animation!
// for this example, just slid both fromView and toView to the left at the same time
// meaning fromView is pushed off the screen and toView slides into view
// we also use the block animation usingSpringWithDamping for a little bounce
UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
if (self.reverse == false) {
fromView.transform = offScreenLeft
}
else {
fromView.transform = offScreenRight
}
toView.transform = CGAffineTransformIdentity
}, completion: { finished in
// tell our transitionContext object that we've finished animating
transitionContext.completeTransition(true)
})
}
// return how many seconds the transiton animation will take
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.3
}
// MARK: UIViewControllerTransitioningDelegate protocol methods
// return the animataor when presenting a viewcontroller
// remmeber that an animator (or animation controller) is any object that aheres to the UIViewControllerAnimatedTransitioning protocol
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
// return the animator used when dismissing from a viewcontroller
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
}
您可以设置 toView
的框架以匹配 fromView
的高度和宽度:
let container = transitionContext.containerView()!
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
toView.frame = CGRectMake(toView.frame.origin.x, toView.frame.origin.y, fromView.frame.width, fromView.frame.height)
或者像这样:
UIViewController* toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
然后在动画例程快结束时进行设置:
toController.view.frame=fromController.view.frame;
我在我的应用程序中为导航控制器自定义了 Viewcontroller 转换。执行转换时,它没有正确调整子 viewcontroller 内容的大小。默认过渡会调整它的大小。 I have added an example project on Github to demonstrate the issue.
内嵌的VCNavigation Controller
import UIKit
class PopoverVCViewController: UIViewController, UIViewControllerTransitioningDelegate, UINavigationControllerDelegate {
let animator = Animator()
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
animator.reverse = operation == .Pop
return animator
}
}
动画师
class Animator: NSObject, UIViewControllerAnimatedTransitioning {
var reverse: Bool = false
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
// get reference to our fromView, toView and the container view that we should perform the transition in
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)
// start the toView to the right of the screen
if (self.reverse == false) {
toView.transform = offScreenRight
}
else {
toView.transform = offScreenLeft
}
// add the both views to our view controller
container.addSubview(toView)
container.addSubview(fromView)
// get the duration of the animation
// DON'T just type '0.5s' -- the reason why won't make sense until the next post
// but for now it's important to just follow this approach
let duration = self.transitionDuration(transitionContext)
// perform the animation!
// for this example, just slid both fromView and toView to the left at the same time
// meaning fromView is pushed off the screen and toView slides into view
// we also use the block animation usingSpringWithDamping for a little bounce
UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
if (self.reverse == false) {
fromView.transform = offScreenLeft
}
else {
fromView.transform = offScreenRight
}
toView.transform = CGAffineTransformIdentity
}, completion: { finished in
// tell our transitionContext object that we've finished animating
transitionContext.completeTransition(true)
})
}
// return how many seconds the transiton animation will take
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.3
}
// MARK: UIViewControllerTransitioningDelegate protocol methods
// return the animataor when presenting a viewcontroller
// remmeber that an animator (or animation controller) is any object that aheres to the UIViewControllerAnimatedTransitioning protocol
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
// return the animator used when dismissing from a viewcontroller
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self
}
}
您可以设置 toView
的框架以匹配 fromView
的高度和宽度:
let container = transitionContext.containerView()!
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
toView.frame = CGRectMake(toView.frame.origin.x, toView.frame.origin.y, fromView.frame.width, fromView.frame.height)
或者像这样:
UIViewController* toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
然后在动画例程快结束时进行设置:
toController.view.frame=fromController.view.frame;