UIButton事件响应区域的研究

最近因为项目需求,需要仿照微信语音聊天界面,就研究了一下UIButton的事件响应。“按住说话”,“松开结束”,“向上移动,取消发送”这种逻辑,一看使用UIButton的响应事件做应该最简单。可是尝试过使用UIButton的响应事件UIControlEventTouchUpInside等响应事件区域的朋友可能就不会这样认为了。下面是我对UIButton响应事件区域的详细研究。
UIButton响应事件:

UIControlEventTouchUpInside
UIControlEventTouchUpOutside
UIControlEventTouchDragInside                                   
UIControlEventTouchDragOutside                                  
UIControlEventTouchDragEnter                                    
UIControlEventTouchDragExit

先说结论:事件UpInside和UpOutside的切换的临界值为70;事件DragInside和DragOutside的切换的临界值为70;事件DragEnter和DragExit的切换的临界值为70。可能苹果觉得人的手指比较小,所以事件的边界值设置多出了70个像素。所以如果要想自定义这个临界值,可以参考下面的代码(主要逻辑:计算手指的位置和超出button的距离)。

贴上代码:
CGFloat const kBoundsExtension = 10.f;

// create button
    UIButton *button = [UIButton new];
    [self.view addSubview:button];
    button.frame = CGRectMake(0, 0, 100, 40);
    button.center = self.view.center;
    [button setTitle:@"按钮" forState:UIControlStateNormal];
    button.backgroundColor = [UIColor lightGrayColor];
    
    // add actions
    [button addTarget:self action:@selector(buttonTouchUp:withEvent:) forControlEvents:UIControlEventTouchUpInside];
    [button addTarget:self action:@selector(buttonTouchUp:withEvent:) forControlEvents:UIControlEventTouchUpOutside];
    [button addTarget:self action:@selector(buttonDrag:withEvent:) forControlEvents:UIControlEventTouchDragInside];
    [button addTarget:self action:@selector(buttonDrag:withEvent:) forControlEvents:UIControlEventTouchDragOutside];
// upinside / upoutside
- (void)buttonTouchUp:(UIButton *)sender withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGRect outerBounds = CGRectInset(sender.bounds, -1 * kBoundsExtension, -1 * kBoundsExtension);
    BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:sender]);
    if (touchOutside) {
        // UIControlEventTouchUpOutside
        NSLog(@"----UpOutside");
    } else {
        // UIControlEventTouchUpInside
        NSLog(@"----UpInside");
    }
}

// dragin / dragout / dragEnter / dragExit
- (void)buttonDrag:(UIButton *)sender withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGRect outerBounds = CGRectInset(sender.bounds, -1 * kBoundsExtension, -1 * kBoundsExtension);
    BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:sender]);
    if (touchOutside) {
        BOOL previewTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:sender]);
        if (previewTouchInside) {
            NSLog(@"----DragExit");
            // UIControlEventTouchDragExit
        } else {
            // UIControlEventTouchDragOutside
            NSLog(@"----DragOutside");
        }
    } else {
        BOOL previewTouchOutside = !CGRectContainsPoint(outerBounds, [touch previousLocationInView:sender]);
        if (previewTouchOutside) {
            // UIControlEventTouchDragEnter
            NSLog(@"----DragEnter");
        } else {
            // UIControlEventTouchDragInside
            NSLog(@"----DragInside");
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1,点击事件和touch事件的关系 自定义UIButton并在其中重写以下方法: 添加UIButton并监听UIC...
    喵子G阅读 11,881评论 3 15
  • 好奇触摸事件是如何从屏幕转移到APP内的?困惑于Cell怎么突然不能点击了?纠结于如何实现这个奇葩响应需求?亦或是...
    Lotheve阅读 58,945评论 51 604
  • 在iOS开发中经常会涉及到触摸事件。本想自己总结一下,但是遇到了这篇文章,感觉总结的已经很到位,特此转载。作者:L...
    WQ_UESTC阅读 11,306评论 4 26
  • 一、简介 <<UIButton(按钮) : 既能显示文字,又能显示图片,还能随时调整内部图片和文字的位置,实现了监...
    无邪8阅读 10,963评论 0 2
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 13,900评论 6 13