iOS仿QQ侧滑菜单

作者: 此心不改 | 来源:发表于2016-05-27 11:35 被阅读2724次

    第一次在简书上写文章。

    今天我要记录下如何拿UITabBarController做QQ侧滑菜单效果:

    首先要了解UITabBarController的层级结构:

    023CE646-7DF4-485F-BBBB-118CADA799DC.png

    UITabBarController加载的其它UIViewController的View都是被添加在UITransitionView上(这是一个私有API),UITransitionView在self.view的0层,UITabBar在的第一层。

    所以我的思路是这样的:

    • UITransitionView与UITabBar转移到一个新的View1上去,作为滑动的部分;
    • 在View1与self.view之间再添加一个View2,作为菜单的容器;
    • 给View1添加相应的手势响应;


      29563C1E-F1D5-45D2-869A-961B6864B8A1.png

    代码:

    #import <UIKit/UIKit.h>
    @protocol SlideTab_VC_TCVDelegate <NSObject>
    
    @optional
    -(void)didOpenMenu:(UIView*)menu;
    -(void)didCloseMenu:(UIView*)menu;
    
    @end
    
    @interface SlideTab_VC : UITabBarController
    
    @property(strong, nonatomic)UIView *mMenuV;
    
    @property(weak, nonatomic)id <SlideTab_VC_TCVDelegate> mDelegate;
    
    -(void)openMenu;
    -(void)closeMenu;
    
    @end
    
    
    
    #import "SlideTab_VC.h"
    
    #define DEVICE_W [UIScreen mainScreen].bounds.size.width
    
    @interface SlideTab_VC ()<UITabBarDelegate>{
        CGFloat _centerMaxX;
    }
    
    @property(strong, nonatomic)UIView *mTransitionView;
    
    @property(strong, nonatomic)UITapGestureRecognizer *mTapGester;
    @property(assign, nonatomic)BOOL mMenuIsOpen;
    
    @property(strong, nonatomic)UITabBar *mTabBar;
    
    @end
    
    @implementation SlideTab_VC
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        self.view.backgroundColor = [UIColor purpleColor];
        _mMenuIsOpen = NO;
        _centerMaxX = DEVICE_W*3/2-80.0f;
        [self initMTransitionView];
        [self addGestureForMTransitionView];
    }
    
    #pragma mark 菜单懒加载
    -(void)setMMenuV:(UIView *)mMenuV{
        if (mMenuV!=nil) {
            _mMenuV = mMenuV;
            [self.view insertSubview:_mMenuV atIndex:0];
        }
    }
    
    #pragma mark 打开菜单
    -(void)openMenu{
       
        CGPoint center = self.mTransitionView.center;
        center.x = _centerMaxX;
        [UIView animateWithDuration:0.15f animations:^{
            self.mTransitionView.center = center;
            if (_mDelegate != nil&& [_mDelegate respondsToSelector:@selector(didOpenMenu:)]) {
            [_mDelegate didOpenMenu:_mMenuV];
        }
        }];
        [self mTransitionSubViewsEnable:NO];
    }
    #pragma mark 关闭菜单
    -(void)closeMenu{
      
        CGPoint center = self.mTransitionView.center;
        center.x = DEVICE_W/2;
        [UIView animateWithDuration:0.15f animations:^{
            self.mTransitionView.center = center;
        } completion:^(BOOL finished) {
            [self mTransitionSubViewsEnable:YES];
            if (_mDelegate != nil&& [_mDelegate respondsToSelector:@selector(didCloseMenu:)]) {
            [_mDelegate didCloseMenu:_mMenuV];
        }
        }];
    }
    
    #pragma mark Transition用户交互使能
    -(void)mTransitionSubViewsEnable:(BOOL)enable{
        for (UIView *tmp in self.mTransitionView.subviews) {
            tmp.userInteractionEnabled = enable;
        }
        if (enable) {
            [self.mTransitionView removeGestureRecognizer:_mTapGester];
        }else{
            [self.mTransitionView addGestureRecognizer:_mTapGester];
        }
    }
    
    #pragma mark 配置mTransitionView
    -(void)initMTransitionView{
        for (UIView *tmp in self.view.subviews) {
            
            [tmp removeFromSuperview];
                
            [self.mTransitionView addSubview:tmp];
        }
        [self.view addSubview:self.mTransitionView];
    }
    
    #pragma mark 拖动手势动作
    -(void)panAction:(UIPanGestureRecognizer*)pan{
        CGPoint location = [pan translationInView:pan.view.superview];
        CGPoint center = self.mTransitionView.center;
        
        if (pan.state==UIGestureRecognizerStateEnded) {
            if (center.x<_centerMaxX*0.5+DEVICE_W*0.25){
                [self closeMenu];
            }else{
                [self openMenu];
            }
        }else if(pan.state==UIGestureRecognizerStateChanged){
            
            if (location.x<0) {//向左滑
                center.x = center.x+location.x<=DEVICE_W/2? DEVICE_W/2 : center.x+location.x;
            }else{
                center.x = center.x+location.x>=_centerMaxX? _centerMaxX : center.x+location.x;
            }
            
            self.mTransitionView.center = center;
            [pan setTranslation:CGPointMake(0, 0) inView:pan.view.superview];
        }
    }
    
    #pragma mark 添加手势
    -(void)addGestureForMTransitionView{
        
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
        [_mTransitionView addGestureRecognizer:pan];
        
        _mTapGester = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction)];
    }
    
    #pragma mark--懒加载
    -(UIView *)mTransitionView{
        if (_mTransitionView==nil) {
            _mTransitionView = [[UIView alloc]initWithFrame:self.view.bounds];
        }
        return _mTransitionView;
    }
    
    -(void)tapAction{
        CGFloat x = _mTransitionView.center.x;
        if (x>=_centerMaxX) {
            [self closeMenu];
        }
    }
    
    @end
    

    相关文章

      网友评论

        本文标题:iOS仿QQ侧滑菜单

        本文链接:https://www.haomeiwen.com/subject/fhzxdttx.html