[英]Prevent interaction on subview of UITableViewCell
我會說你的實現存在缺陷,或者你有X / Y問題。 考慮將單個單元格拆分為兩個單獨的單元格,並禁用底部單元格上的選擇。
如果您必須繼續此實現,請考慮禁用整個單元格上的選擇。 將手勢識別器放在頂部子視圖中,並在觸摸時手動調用didSelectRowAtIndexPath:
.
你可以通過命中測試來轉發或取消觸摸
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
if let hitView = super.hitTest(point, withEvent: event) {
if hitView.isKindOfClass(CustomSubviewClass) {
return nil
} else {
return hitView
}
} else {
return nil
}
}
我完全同意JAL ,你需要檢查你所有的細胞結構,但我也知道有時候,在某些情況下,重構是不可能的。
所以,我想這個,假設你有一個由兩個視圖組成的CustomTableViewCell
,例如view1和view2命名:
代碼:
class MyView1 : UIView {
var isTouched : Bool = false
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.isTouched = true
self.nextResponder()?.touchesBegan(touches, withEvent: event)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.isTouched = false
self.nextResponder()?.touchesEnded(touches, withEvent: event)
}
}
class MyView2 : UIView {
var isTouched : Bool = false
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.isTouched = true
self.nextResponder()?.touchesBegan(touches, withEvent: event)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.isTouched = false
self.nextResponder()?.touchesEnded(touches, withEvent: event)
}
}
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var myExampleLabel: UILabel!
@IBOutlet weak var view1: MyView1!
@IBOutlet weak var view2: MyView2!
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("situation: myView1 : \(self.view1.isTouched) myView2: \(self.view2.isTouched)")
var responder : UIResponder! = self
while responder.nextResponder() != nil {
responder = responder.nextResponder()
if responder is SimpleTableView.ViewController { // the name of your tableView delegate class
let vc = responder as! ViewController
let indexPath = vc.tableView.indexPathForCell(self)
vc.tableView(vc.tableView, didSelectRowAtIndexPath: indexPath!)
}
}
super.touchesBegan(touches, withEvent: event)
}
}
另一方面,你有一個帶有UITableView
的UIViewController
:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var tableView: UITableView!
var items: [String] = ["We", "Heart", "Swift", "So", "Much"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140.0
self.tableView.registerNib(UINib(nibName: "CustomTableViewCell", bundle:nil), forCellReuseIdentifier: "CustomTableViewCell")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell", forIndexPath: indexPath) as! CustomTableViewCell
cell.myExampleLabel.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomTableViewCell
print("row = %d",indexPath.row)
if cell.view1.isTouched {
print("tableView: touched view 1")
// do whatever you want with cell.view1
// if you want you can disable cell.view2.userInteractionEnabled
}
else {
print("tableView: touched view 2")
// same thing for cell.view2
}
}
}
一些重要的事情 :
不要忘記為兩個視圖設置正確的自定義類,如下圖所示:
實現此功能的一種方法是繞過UITableViewDelegate
方法,並在單元格上使用帶有自定義回調處理程序的IBAction
。
tableView:didSelectRowAtIndexPath
。 UITableViewCell
子類中添加@IBAction func buttonTapped(sender: UIButton)
。 tableView:cellForRowAtIndexPath:
delegate方法中設置單元格上的閉包來處理調用。 示例UITableViewCell
子類:
class MyTableViewCell: UITableViewCell {
var selectionHandler: ((Void) -> Void)?
override func prepareForReuse() {
// Remove the closure when the cell is recycled.
selectionHandler = nil
}
@IBAction func buttonTapped(sender: UIButton) {
// Call the closure when the button is tapped.
selectionHandler?()
}
}
在你的UITableViewController
:
class MyTableViewController: UITableViewController {
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = ....
// Set the closure to be called when the button is tapped.
// Using weak self here to prevent a retain cycle.
cell.selectionHandler = { [weak self] in
self?.selectedCellAtIndexPath(indexPath)
}
return cell
}
// We are not using didSelectRowAtIndexPath
// override func tableView(tableView: UITableView, didSelectRowAtIndexPath: NSIndexPath) {
// }
}
我沒有測試過這段代碼,所以它可能無法編譯,盡管它應該用來說明這個概念。
從表視圖屬性編輯器中,將“ Selection
值設置為“ No Selection
或以編程方式執行。 禁用每個子視圖上的交互,但您想要操作的子視圖除外。 將indexPath行值作為標記傳遞給該子視圖,也許。 或者從UIView
子類化子視圖來存儲indexPath信息。 接下來,對該子視圖實施點擊手勢,並在點擊手勢識別方法上執行您的願望操作。 希望這些應該做你想要的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.