我有一个大的UITableViewCell,里面有2个自定义UIViews。其中一个应该允许交互(选择和取消选择),其中一个视图不应该允许交互。
我知道我可以在整个单元格或每个子视图上启用或禁用交互,但如果我在UIView上禁用交互,则单元格仍会被选中或取消选择。
有没有办法,例如,允许触摸细胞的上半部分而不是底部?
这是我描述的UITableViewCell的截图
答案 0 :(得分:2)
我会说您的实施存在缺陷,或者您有X / Y问题。考虑将单个单元格拆分为两个单独的单元格,并禁用底部单元格上的选择。
如果您必须继续使用此实现,请考虑禁用整个单元格上的选择。将手势识别器放在顶部子视图中,然后手动触摸didSelectRowAtIndexPath:
。
答案 1 :(得分:1)
您可以使用点击测试转发或取消触摸
wire tmpValid = 1, tmpData = 1;
答案 2 :(得分:1)
我完全同意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)
}
}
另一方面,例如UIViewController
UITableView
:
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
}
}
}
一些重要的事情:
不要忘记为两个视图设置正确的自定义类,如下图所示:
答案 3 :(得分:0)
实现此功能的一种方法是绕过UITableViewDelegate
方法,并在单元格上使用带有自定义回调处理程序的IBAction
。
tableView:didSelectRowAtIndexPath
。@IBAction func buttonTapped(sender: UIButton)
子类中添加UITableViewCell
。tableView:cellForRowAtIndexPath:
委托方法中,设置单元格上的闭包以处理调用。示例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) {
// }
}
我没有测试过这段代码,所以它可能无法编译,虽然它应该用来说明这个概念。
答案 4 :(得分:0)
从表格视图属性编辑器中,将Selection
值设置为No Selection
或以编程方式执行。禁用每个子视图上的交互,但您想要操作的子视图除外。将indexPath行值作为标记传递给该子视图,也许。或者从UIView
子类化子视图以存储indexPath信息。接下来,对该子视图实施点击手势,并在点击手势识别方法上执行您的愿望操作。希望这些能做你想做的事。