UIButtonイベント応答領域の研究

3368 ワード

最近,プロジェクトニーズのため,微信音声チャットインタフェースを模倣する必要があり,UIButtonのイベント応答を検討した.「話を押さえる」「終了を緩める」「上へ移動する」「送信をキャンセルする」という論理は、UIBEttonのレスポンスイベントを使うのが一番簡単だと思います.しかし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");
        }
    }
}