美文网首页
UIButton事件响应区域的研究

UIButton事件响应区域的研究

作者: OC笔记 | 来源:发表于2016-11-01 18:26 被阅读0次

    最近因为项目需求,需要仿照微信语音聊天界面,就研究了一下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");
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:UIButton事件响应区域的研究

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