继承 UINavigationController 写返回动画

<span style="background-color: rgb(255, 255, 255);"><span style="font-family:FangSong_GB2312;font-size:18px;"><strong><img alt="难过" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/sad.gif" />以前看别人写 手势滑动返回动画 总是出现各种bug 经过自己修改几乎能满足所有的开发需求</strong></span></span>


1.首先来看下头文件实现

(没得什么变化)
<span style="color:#993300;">#define KEY_WINDOW  [[UIApplication sharedApplication]keyWindow]
#define kkBackViewHeight [UIScreen mainScreen].bounds.size.height
#define kkBackViewWidth [UIScreen mainScreen].bounds.size.width

#define iOS7  ( [[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending )


#define lengthForT UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone?150:200

#define  windowHeitht  UIWindow *screenWindow = [[UIApplication sharedApplication] keyWindow]

// 背景视图起始frame.x
#define startX -200;</span>

<span style="color:#ff0000;">@interface</span> BABaseNavController : UINavigationController

{
    CGFloat startBackViewX;
}

<span style="color:#ff0000;">@property (nonatomic,strong)</span><span style="color:#6666cc;">UIPanGestureRecognizer</span> *recognizer; //方便随时关闭手势达到有些界面不准用户手势返回

<span style="color:#ff0000;">@property (nonatomic,retain)</span> <span style="color:#6666cc;">UIView</span> *backgroundView;

<span style="color:#ff0000;">@property (nonatomic,strong)</span> <span style="color:#6666cc;">NSMutableArray</span> *screenShotsList;
<span style="color:#ff0000;">@property (nonatomic,assign)</span> <span style="color:#ff0000;">BOOL</span> isMoving;

// 默认为特效开启
<span style="color:#ff0000;">@property (nonatomic, assign)</span> <span style="color:#ff0000;">BOOL</span> canDragBack;<span style="color:#ff6666;">
</span>

2.来看看如何实现的吧

a. 初始化

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        
        NSMutableArray * newArr = [[NSMutableArray alloc]init];
        self.screenShotsList = newArr; //存放上一个界面截图数组
        self.canDragBack = YES;
        weighForScreen = Screen_WIDTH; //<span style="font-family: Arial, Helvetica, sans-serif;">weighForScreen是</span>设备的宽度
//        [self setup];//自己对<span style="font-family: Arial, Helvetica, sans-serif;">UINavigationController 一些设置</span>

    }
    return self;
}
b.添加阴影背景和手势设置

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    UIImageView *shadowImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"leftside_shadow_bg"]];
    shadowImageView.frame = CGRectMake(-10, 0, 10, self.view.frame.size.height);
    [self.view addSubview:shadowImageView];
    
}
-(UIPanGestureRecognizer *)recognizer{
    if (!_recognizer) {
        _recognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self
                                                                 action:@selector(paningGestureReceive:)];
        [_recognizer delaysTouchesBegan];
        [self.view addGestureRecognizer:_recognizer];
    }
    return _recognizer;

}
c.重写push和pop 方法

      

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    UIImage * img = [self capture];
    
    if (img == nil) {
        img = [[UIImage alloc]init];
    }
    
    [self.screenShotsList addObject:img];
    if (self.viewControllers.count == 0) {
        [self.recognizer setEnabled:NO]; //这里我是按自己需求进行手势的打开与关闭。ps:可以在这里隐藏bar 在pop 显示bar
    }else{
    
        [self.recognizer setEnabled:YES];
    }
    [super pushViewController:viewController animated:animated];
}

- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
    if (self.viewControllers.count == 2) {
        [self.recognizer setEnabled:NO];//同理
    }
    [self.screenShotsList removeLastObject];
    return [super popViewControllerAnimated:animated];
}
       d.截屏

- (UIImage *)capture
{
//这里是截取当前window 的屏幕
    UIWindow *screenWindow = [[UIApplication sharedApplication] keyWindow];
    //    UIGraphicsBeginImageContextWithOptions(screenWindow.frame.size, self.view.opaque, 0.0);
    
    UIGraphicsBeginImageContext(screenWindow.size);
    [screenWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}
    e.核心代码手势

#pragma mark - Gesture Recognizer -

- (void)paningGestureReceive:(UIPanGestureRecognizer *)recoginzer
{
    
    
    if (self.viewControllers.count <= 1 || !self.canDragBack) return;
    
    CGPoint touchPoint = [recoginzer locationInView:KEY_WINDOW];
    
    if (recoginzer.state == UIGestureRecognizerStateBegan) {
        
        _isMoving = YES;
        startTouch = touchPoint;
        [self.backgroundView removeFromSuperview];
        self.backgroundView = nil;
        blackMask = nil;
        CGRect frame = [UIScreen mainScreen].bounds;
        
        self.backgroundView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width , frame.size.height)];
        [self.view.superview insertSubview:self.backgroundView belowSubview:self.view];
        
        blackMask = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width , frame.size.height)];
        blackMask.backgroundColor = [UIColor blackColor];
        [self.backgroundView addSubview:blackMask];
        
        self.backgroundView.hidden = NO;
        
        if (lastScreenShotView){
            [lastScreenShotView removeFromSuperview];
            lastScreenShotView = nil;
        }
        lastScreenShot = [self.screenShotsList lastObject];
        lastScreenShotView = [[UIImageView alloc]initWithImage:lastScreenShot];
        
        startBackViewX = startX;
        [lastScreenShotView setFrame:CGRectMake(startBackViewX,
                                                lastScreenShotView.frame.origin.y,
                                                lastScreenShotView.frame.size.height,
                                                lastScreenShotView.frame.size.width)];
        
        [self.backgroundView insertSubview:lastScreenShotView belowSubview:blackMask];
        
    }else if (recoginzer.state == UIGestureRecognizerStateEnded){
        
        int cont = 50;
        if (touchPoint.x - startTouch.x > cont)
        {
            [UIView animateWithDuration:0.3 animations:^{
                [self moveViewWithX:weighForScreen];
            } completion:^(BOOL finished) {
                
                
                CGRect frame = self.view.frame;
                frame.origin.x = 0;
                self.view.frame = frame;
                
                _isMoving = NO;
                [self popViewControllerAnimated:NO];
            }];
        }
        else
        {
            [UIView animateWithDuration:0.3 animations:^{
                [self moveViewWithX:0];
            } completion:^(BOOL finished) {
                _isMoving = NO;
                self.backgroundView.hidden = YES;
            }];
            
        }
        return;
        
    }else if (recoginzer.state == UIGestureRecognizerStateCancelled){
        
        [UIView animateWithDuration:0.3 animations:^{
            [self moveViewWithX:0];
        } completion:^(BOOL finished) {
            _isMoving = NO;
            self.backgroundView.hidden = YES;
        }];
        
        return;
    }
    
    if (_isMoving) {
        [self moveViewWithX:touchPoint.x - startTouch.x];
    }
}

- (void)moveViewWithX:(float)x
{
    x = x>weighForScreen?weighForScreen:x;
    x = x<0?0:x;
    
    CGRect frame = self.view.frame;
    frame.origin.x = x;
    self.view.frame = frame;
    
    float alpha = 0.4 - (x/800);
    
    blackMask.alpha = alpha;
    
    CGFloat aa = abs(startBackViewX)/kkBackViewWidth;
    CGFloat y = x*aa;
    CGFloat lastScreenShotViewHeigh = kkBackViewHeight;
    
    [lastScreenShotView setFrame:CGRectMake(startBackViewX+y,
                                            0,
                                            kkBackViewWidth,
                                            lastScreenShotViewHeigh)];
    
}



大笑基本的实现都在上面了,如果想满足不同的返回动画,只需修改其中的部分代码 都能满足返回动画。

最后希望能帮助你      




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值