在UINavigationControllerDelegate代理方法中 (实现此代理方法必须遵循UINavigationControllerDelegate)
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
}
此方法返回一个继承UIViewControllerAnimatedTransitioning协议的对象
我们只要在创建一个 遵循UIViewControllerAnimatedTransitioning协议的对象,并自定义自己的转场动画即可实现自定义转场动画
@interface KKNavAnimation : NSObject <UIViewControllerAnimatedTransitioning>
@end
并在.m文件中实现
#此方法设置转场动画的时间
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return 0.5f;
}
#此方法中实现自定义转场动画 根据自己的需求来
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
#所有转场动画的视图都要添加到此view上
UIView *contentView = transitionContext.containerView;
contentView.backgroundColor = [UIColor blackColor];
#获取将要push到的界面
UIViewController* toVc = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
__block UIView *imageView = [UIView new];
imageView.frame = self.isPush? self.origionRect : self.desRect;
imageView.backgroundColor = self.imageView.backgroundColor;
[contentView addSubview:toVc.view];
UIView *hazylayerView = nil;
if (!_isPush) {
hazylayerView = [UIView new];
NSLog(@"add layer");
hazylayerView.backgroundColor = [UIColor yellowColor];
[contentView addSubview:hazylayerView];
}
[contentView addSubview:imageView];
toVc.view.alpha = 0;
[UIView animateWithDuration:0.2 animations:^{
toVc.view.alpha = 1;
}];
[UIView animateWithDuration:0.3 animations:^{
imageView.frame = self.isPush? self.desRect : self.origionRect;
// imageView.frame = self.desRect;
NSLog(@"%@",NSStringFromCGRect(imageView.frame));
} completion:^(BOOL finished) {
if (self.isPush) {
#如果是push 此处设置YES即可 如何是pop 并且要自定义侧滑返回 需要判断
[transitionContext completeTransition:YES];
} else {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
if ([transitionContext transitionWasCancelled]) {
//手势取消了,原来隐藏的imageView要显示出来
// fromVC.imageView.hidden = NO;
// fromVC.titleLabel.hidden = NO;
}else{
//手势成功,cell的imageView也要显示出来
// cell.imageView.hidden = NO;
// cell.detailTextLabel.hidden = NO;
}
}
// if (hazylayerView) {
// [hazylayerView removeFromSuperview];
// }
[imageView removeFromSuperview];
imageView = nil;
}];
}
写到这里push动画已经实现了
但是会发现侧滑返回的时候 并没有执行转场动画, 设置手势需要在另一个代理方法中返回一个遵守UIViewControllerInteractiveTransitioning协议的对象
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController{
if (!_isPush) {
return self.interac.isInteractive == YES ? self.interac : nil;
}
return nil;
}
我们可以创建一个继承UIPercentDrivenInteractiveTransition的对象
@interface KKNavTransitionInteractive : UIPercentDrivenInteractiveTransition
@end
然后在.m文件中 给控制器添加手势代理方法
//给控制器的View添加相应的手势
- (void)addPanGestureForViewController:(UIViewController *)viewController{
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
self.viewController = viewController;
[viewController.view addGestureRecognizer:pan];
}
- (void)handleGesture:(UIPanGestureRecognizer *)panGesture
{
CGPoint translation = [panGesture translationInView:panGesture.view];
CGFloat percentComplete = 0.0;
//左右滑动的百分比
percentComplete = translation.x / (_viewController.view.frame.size.width);
percentComplete = fabs(percentComplete);
// NSLog(@"%f",percentComplete);
switch (panGesture.state) {
case UIGestureRecognizerStateBegan:
[_viewController.navigationController popViewControllerAnimated:YES];
break;
case UIGestureRecognizerStateChanged:{
//手势过程中,通过updateInteractiveTransition设置转场过程动画进行的百分比,然后系统会根据百分比自动布局动画控件,不用我们控制了
[self updateInteractiveTransition:percentComplete];
break;
}
case UIGestureRecognizerStateEnded:{
//手势完成后结束标记并且判断移动距离是否过半,过则finishInteractiveTransition完成转场操作,否者取消转场操作,转场失败
if (percentComplete > 0.5) {
[self finishInteractiveTransition];
}else{
[self cancelInteractiveTransition];
}
break;
}
default:
break;
}
}
大功告成
共勉
网友评论