UIButton事件响应区域的研究

2016-11-01  本文已影响0人  OC笔记

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

猜你喜欢

热点阅读