今天给大家详细介绍一下IOS手势的用法,最后给大家分享一点干货,《基于手势识别的侧滑展开菜单栏》,这个功能在开发中会经常用到,是非常重要的。
一、UIGestureRecognizer介绍
手势在ios经常用到,可以说是非常重要的存在,在之前,大部分都是通过touch方法来进行手势的判定,但是在ios系统3.2之后,添加了UIGestureRecongnizer抽象类,抽象出了几个子类
UIRotationGestureRecognizer (旋转)
UILongPressGestureRecognizer (长按)
这些手势都很简单,基本上明白一个的用法,其他的也就都明白了,所以我们今天就以 拖动为例,给大家做一个侧滑展开菜单栏
我们先来了解一下这些手势的基本用法
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];
}
这样,就可以了,完美运行,下面我把代码给大家,大家可以尝试一下用轻扫手势侧滑出菜单栏,看看两者直接有什么区别
代码示例