首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS 多 UIView 添加點擊手勢:為何共用 UITapGestureRecognizer 失效?

     編輯:程式設計綜合問答

問題現象

同一 UITapGestureRecognizer 實例分別添加給 sendView、payView、receiverView、commentView,結果**只有最後添加的 commentView 能響應點擊**。

根本原因

UIGestureRecognizer **一次只能附屬於一個 View**。當對同一手勢實例呼叫 addGestureRecognizer: 時,系統會**自動從先前的 View 移除**,再添加到新 View。因此前三個 View 實際上並未持有該手勢。

正確做法:每個 View 獨立實例

// 方式一:分別建立實例(推薦,語意清晰)
UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewClick:)];
[self.sendView addGestureRecognizer:tap1];

UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewClick:)];
[self.payView addGestureRecognizer:tap2];

UITapGestureRecognizer *tap3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewClick:)];
[self.receiverView addGestureRecognizer:tap3];

UITapGestureRecognizer *tap4 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewClick:)];
[self.commentView addGestureRecognizer:tap4];

進階:統一處理點擊邏輯

- (void)viewClick:(UITapGestureRecognizer *)sender {
    UIView *tappedView = sender.view;
    if (tappedView == self.sendView) { /* 發送邏輯 */ }
    else if (tappedView == self.payView) { /* 支付邏輯 */ }
    else if (tappedView == self.receiverView) { /* 收件邏輯 */ }
    else if (tappedView == self.commentView) { /* 評論邏輯 */ }
}

替代方案:單一手勢 + hitTest(不推薦)

在共同父視圖添加手勢,通過 hitTest:withEvent: 判斷點擊落在哪個子視圖。**缺點**:事件傳遞鏈複雜、易與子視圖自身手勢衝突、難以維護。

Swift 版本

let views = [sendView, payView, receiverView, commentView]
views.forEach { view in
    let tap = UITapGestureRecognizer(target: self, action: #selector(viewClick(_:)))
    view.addGestureRecognizer(tap)
}

@objc func viewClick(_ sender: UITapGestureRecognizer) {
    switch sender.view {
    case sendView: /* ... */ break
    case payView: /* ... */ break
    case receiverView: /* ... */ break
    case commentView: /* ... */ break
    default: break
    }
}

總結

一個手勢識別器只能綁定一個視圖。多視圖需多實例。這是 UIKit 設計決策,非 Bug。記住:addGestureRecognizer: 會自動從舊視圖移除。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved