3 回答
TA贡献1794条经验 获得超8个赞
要使用导航控制器(UINavigationController)进行自定义转换,您应该:
定义您的视图控制器以符合UINavigationControllerDelegate协议。例如,您可以在视图控制器的.m文件中具有私有类扩展名,该扩展名指定对此协议的符合性:
@interface ViewController () <UINavigationControllerDelegate>
@end
确保您确实将视图控制器指定为导航控制器的委托:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.delegate = self;
}
实现animationControllerForOperation您的视图控制器:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController*)fromVC
toViewController:(UIViewController*)toVC
{
if (operation == UINavigationControllerOperationPush)
return [[PushAnimator alloc] init];
if (operation == UINavigationControllerOperationPop)
return [[PopAnimator alloc] init];
return nil;
}
实现用于推送和弹出动画的动画制作器,例如:
@interface PushAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@end
@interface PopAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@end
@implementation PushAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.5;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[[transitionContext containerView] addSubview:toViewController.view];
toViewController.view.alpha = 0.0;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.alpha = 1.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
@implementation PopAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.5;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view];
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromViewController.view.alpha = 0.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
确实会出现淡入淡出的过渡,但是您应该随心所欲地自定义动画。
如果您想处理交互式手势(例如,从左向右滑动本机滑动之类的东西),则必须实现一个交互控制器:
定义交互控制器(符合的对象UIViewControllerInteractiveTransitioning)的属性:
@property (nonatomic, strong) UIPercentDrivenInteractiveTransition *interactionController;
这UIPercentDrivenInteractiveTransition是一个不错的对象,它会根据手势的完成程度来繁琐地更新自定义动画。
将手势识别器添加到视图。在这里,我只是实现左手势识别器来模拟弹出:
UIScreenEdgePanGestureRecognizer *edge = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFromLeftEdge:)];
edge.edges = UIRectEdgeLeft;
[view addGestureRecognizer:edge];
实现手势识别处理程序:
/** Handle swipe from left edge
*
* This is the "action" selector that is called when a left screen edge gesture recognizer starts.
*
* This will instantiate a UIPercentDrivenInteractiveTransition when the gesture starts,
* update it as the gesture is "changed", and will finish and release it when the gesture
* ends.
*
* @param gesture The screen edge pan gesture recognizer.
*/
- (void)handleSwipeFromLeftEdge:(UIScreenEdgePanGestureRecognizer *)gesture {
CGPoint translate = [gesture translationInView:gesture.view];
CGFloat percent = translate.x / gesture.view.bounds.size.width;
if (gesture.state == UIGestureRecognizerStateBegan) {
self.interactionController = [[UIPercentDrivenInteractiveTransition alloc] init];
[self popViewControllerAnimated:TRUE];
} else if (gesture.state == UIGestureRecognizerStateChanged) {
[self.interactionController updateInteractiveTransition:percent];
} else if (gesture.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [gesture velocityInView:gesture.view];
if (percent > 0.5 || velocity.x > 0) {
[self.interactionController finishInteractiveTransition];
} else {
[self.interactionController cancelInteractiveTransition];
}
self.interactionController = nil;
}
}
在导航控制器委托中,还必须实现interactionControllerForAnimationController委托方法
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController {
return self.interactionController;
}
如果您在Google上搜索“ UINavigationController自定义过渡教程”,那么您将获得很多成功。或参阅WWDC 2013 Custom Transitions视频。
TA贡献1858条经验 获得超8个赞
您可能想在之前添加以下代码 addSubview
toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController];
来自另一个问题,在iOS 9上使用navigationcontroller为推送动画进行自定义转换
从Apple的finalFrameForViewController文档中:
返回指定视图控制器视图的结束帧矩形。
此方法返回的矩形表示过渡结束时相应视图的大小。对于演示过程中涉及的视图,此方法返回的值可能是CGRectZero,但也可能是有效的框架矩形。
- 3 回答
- 0 关注
- 529 浏览
添加回答
举报