免费开源的iOS开发学习平台

UIView详解:6-响应用户交互事件

UIView的对象都具有响应用户交互的能力,因为UIView继承自UIResponder。在初始化视图对象的过程中,可以给UIView对象添加手势,以响应用户交互。另外,对于自定义视图类,可以通过实现其有关触摸的相关方法,来定义用户交互的动作。

1、与用户交互事件相关的属性

UIView类中,userInteractionEnabled属性可以用来定义视图类对象是否能够响应用户交互。对于某些UIView的子类,例如UILabel,UIImageView,该属性默认情况下是关闭的,因此如果需要响应手势等交互事件,需要修改该属性的值为YES。另外,multipleTouchEnabled属性用于设置视图对象能否支持多点触控,默认情况下,其取值是NO。

@property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled; //是否支持用户交互
@property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled; //是否支持多点触控

2、添加手势

对于视图类对象,都可以通过添加手势的方法,来响应用户的交互。一个视图类对象,可以添加多个手势。例如,在一些游戏App中,一个按钮的点击以及长按可以对应不同的操作。UIView类中,与手势相关的属性和方法如下:

@property(nullable, nonatomic,copy) NSArray *gestureRecognizers ;//获取视图对象上的所有手势 
- (void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer NS_AVAILABLE_IOS(3_2);//添加手势
- (void)removeGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer NS_AVAILABLE_IOS(3_2);//移除手势

以下示例代码为一个UIView对象添加了点击和长按手势:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //添加长按手势
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction)];
    [self.myView addGestureRecognizer:longPress];
    
    //添加点击手势
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
    [self.myView addGestureRecognizer:tap];  
    
    //打印所有的手势对象
    NSLog(@"myview gesture : %@", self.myView.gestureRecognizers);
}
  • 实现长按手势触发时的动作
-(void)longPressAction{
    NSLog(@"%s",__func__);
   UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"长按了" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alertView show];
}
  • 实现点击手势触发时的动作
-(void) tapAction {
    NSLog(@"%s",__func__);
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"点击了" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alertView show];
}

3、自定义视图类实现touches系列方法

由于UIView继承自UIResponder,因此UIView也同时具有UIResponder的属性和方法。在UIResponder类的定义中,提供了一些响应用户点击操作的方法,如下所示。在自定义视图类中,如果需要响应用户的点击操作,也可以通过重写这些方法来实现用户交互。

需要特别注意的一点是:视图类能够响应用户交互的范围,一定不能超出视图frame所划定的区域,大家可以做一个测试:在父视图中再添加一个更大的子视图,点击超出父视图的范围,看看是否可以调用touchesBegan:方法。

- (void)touchesBegan:(NSSet *)touches withEvent:(nullable UIEvent *)event; //点击了视图
- (void)touchesMoved:(NSSet *)touches withEvent:(nullable UIEvent *)event;//在视图区域中移动
- (void)touchesEnded:(NSSet *)touches withEvent:(nullable UIEvent *)event;//点击完成

示例代码:

/*配置View点击,作用域在于对象的frame范围内*/
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"%s 接收到触摸事件",__func__);
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"%s, event: %@",__func__,event);
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"点击了视图" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alertView show];  
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"%s",__func__);
}

示例代码

https://github.com/99ios/7.2.6