iOS开发UI进阶篇 — 基于手势识别的侧滑展开菜单栏


今天给大家详细介绍一下IOS手势的用法,最后给大家分享一点干货,《基于手势识别的侧滑展开菜单栏》,这个功能在开发中会经常用到,是非常重要的。


一、UIGestureRecognizer介绍



手势在ios经常用到,可以说是非常重要的存在,在之前,大部分都是通过touch方法来进行手势的判定,但是在ios系统3.2之后,添加了UIGestureRecongnizer抽象类,抽象出了几个子类


这些手势都很简单,基本上明白一个的用法,其他的也就都明白了,所以我们今天就以 拖动为例,给大家做一个侧滑展开菜单栏

我们先来了解一下这些手势的基本用法

1、缩放手势

UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc]
                                                        initWithTarget:self
                                                        action:@selector(handlePinch:)];
[imageView addGestureRecognizer:pinchGestureRecognizer];

回调方法


- (void) handlePinch:(UIPinchGestureRecognizer*) recognizer
{
    recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    recognizer.scale = 1;
}

2.拖动手势

UIPanGestureRecognizer * panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
    //添加手势到 tabBarController.view
    [tabBarController.view addGestureRecognizer:panRecognizer];

回调方法

- (void) handlePan:(UIPanGestureRecognizer*) recognizer
{
    CGPoint translation = [recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                   recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointZero inView:self.view];
    
}

3.旋转手势


/**
 *  处理旋转手势
 *
 *  @param recognizer 旋转手势识别器对象实例
 */
- (void)handleRotation:(UIRotationGestureRecognizer *)recognizer {
    recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
    recognizer.rotation = 0.0;
}




大家需要注意的是,一个手势只能对应一个View, 但是一个View可以有多个手势


二、拖动手势实现侧滑菜单栏


1.新建工程


文件结构如图所示:



2.创建MenuView


在ViewController里面创建一个menuView,作为最底层

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //新建一个菜单栏放在最底部,设置大小,这样就可以在拖动上层界面的时候,将底下的菜单栏漏出来
    UIView * menuView = [[UIView alloc] init];
    [self.view addSubview:menuView];
    menuView.frame = CGRectMake(0, 0, self.view.frame.size.width * 0.8, self.view.frame.size.height);
    //设置菜单栏的颜色为红色
    menuView.backgroundColor = [UIColor redColor];
    
    
    CXRSplitController * splitViewController = [[CXRSplitController alloc] init];
    //将splitViewController的控制器和根视图都交由跟控制器进行管理
    [self addChildViewController:splitViewController];
    [self.view addSubview:splitViewController.view];
    
    
}

3.创建CXRSplitController

CXRSplitController 作为 tabBarController 的存在,拖动手势在响应的时候,其实拖动的是CXRSplitController ,所以我们需要在上面添加一个UITabBarController,并且添加三个页面
//新建一个tabBarController
    UITabBarController * tabBarController = [[UITabBarController alloc] init];
    //将tabBarController交给 CXRSplitController 进行管理
    [self addChildViewController:tabBarController];
    [self.view addSubview:tabBarController.view];
    
    self.tabBarController = tabBarController;
    
    [tabBarController.tabBar setBackgroundImage:[UIImage imageNamed:@"tabbar_bg"]];
    //给tabBarController 添加三个viewController
    UIViewController * mainController = [[UIViewController alloc] init];
    [self setItemImageWithController:mainController image:@"tab_me_nor" selectImage:@"tab_me_press" title:@"主页"];
    mainController.view.backgroundColor = [UIColor colorWithRed:0.980 green:0.765 blue:0.620 alpha:1.000];
    UIViewController * messageController = [[UIViewController alloc] init];
    [self setItemImageWithController:messageController image:@"tab_recent_nor" selectImage:@"tab_recent_press" title:@"消息"];
    messageController.view.backgroundColor = [UIColor colorWithRed:0.949 green:0.525 blue:0.537 alpha:1.000];
    UIViewController *dynamicController = [[UIViewController alloc] init];
    [self setItemImageWithController:dynamicController image:@"tab_qworld_nor" selectImage:@"tab_qworld_press" title:@"动态"];
    dynamicController.view.backgroundColor = [UIColor colorWithRed:0.847 green:0.522 blue:0.702 alpha:1.000];
    

设置图片标题的方法,同时把每一个页面作为导航栏的根视图
- (void)setItemImageWithController:(UIViewController *)viewCotroller image:(NSString *)image selectImage:(NSString *)selectImage title:(NSString *)title {
    
    viewCotroller.title = title;
    
    
    
    viewCotroller.tabBarItem.image = [[UIImage imageNamed:image] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    viewCotroller.tabBarItem.selectedImage = [[UIImage imageNamed:selectImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
#pragma mark - 把 UINavigationController 添加到TabBarController 进行管理
    
    UINavigationController * navController = [[UINavigationController alloc]initWithRootViewController:viewCotroller];
    
    
    [self.tabBarController addChildViewController:navController];
}

到这里,我们的基本框架也就搭建起来了,这也是国内主流APP的结构(可以参照qq)

4.添加手势到tabBarController

 
    UIPanGestureRecognizer * panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)];
    //添加手势到 tabBarController.view
    [tabBarController.view addGestureRecognizer:panRecognizer];

5.实现收拾的回调方法


- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    
    CGPoint point = [recognizer translationInView:self.tabBarController.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + point.x, recognizer.view.center.y);
    CGFloat viewX = recognizer.view.frame.origin.x;
    CGFloat viewY = recognizer.view.frame.origin.y;
    
    recognizer.view.frame = CGRectMake(viewX + point.x, viewY, recognizer.view.frame.size.width, 
                            recognizer.view.frame.size.height);
    
    [recognizer setTranslation:CGPointZero inView:self.tabBarController.view];
}


运行一下,是不是可以拖动了,大家就会发现问题了,我可以任意拖动界面,都超出边界了还能够继续拖动,我们只需要他拖动部分,所以我们需要给他加一个界限

- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
    
    CGPoint point = [recognizer translationInView:self.tabBarController.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + point.x, recognizer.view.center.y);
    CGFloat viewX = recognizer.view.frame.origin.x;
    CGFloat viewY = recognizer.view.frame.origin.y;
    
   
    if (viewX <= 0) {
        
        recognizer.view.frame = CGRectMake(0, viewY, recognizer.view.frame.size.width, recognizer.view.frame.size.height);
    }else if (viewX >= self.view.frame.size.width * 0.8) {
        
        recognizer.view.frame = CGRectMake(self.view.frame.size.width * 0.8, viewY, recognizer.view.frame.size.width, recognizer.view.frame.size.height);
    }else {
        recognizer.view.frame = CGRectMake(viewX + point.x, viewY, recognizer.view.frame.size.width, recognizer.view.frame.size.height);
        
    }

    
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        
   
        if (viewX < 120) {
            [UIView animateWithDuration:0.5 animations:^{
                recognizer.view.frame = CGRectMake(0, viewY, recognizer.view.frame.size.width, recognizer.view.frame.size.height);
            }];
            
        }
        if (viewX > 120) {
            [UIView animateWithDuration:0.5 animations:^{
                recognizer.view.frame = CGRectMake(self.view.frame.size.width * 0.8, viewY, recognizer.view.frame.size.width, recognizer.view.frame.size.height);
            }];
        }
    }
    
    [recognizer setTranslation:CGPointZero inView:self.tabBarController.view];
}

这样,就可以了,完美运行,下面我把代码给大家,大家可以尝试一下用轻扫手势侧滑出菜单栏,看看两者直接有什么区别



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值