tableView - didSelectRowAtIndexPath 未调用

Posted

技术标签:

【中文标题】tableView - didSelectRowAtIndexPath 未调用【英文标题】:tableView - didSelectRowAtIndexPath not called 【发布时间】:2018-09-29 14:25:18 【问题描述】:

我有一个UITableView,它嵌入在UIView 中,充当下拉视图(见图)。但是,它不响应单元格用户触摸(使用didSelectRowAtIndexPath 函数进行测试)。请看下面的代码。

它的工作原理是下拉视图是一个按钮的子视图(在静态UITableViewCell中),因此当按钮被触摸时,下拉视图高度从0变为@ 987654330@(单元格高度也会发生变化)。

我检查了视图层次结构,没有任何东西阻止视图注册触摸。

下拉视图自定义类

class GenderDropDownView: UIView, UITableViewDelegate, UITableViewDataSource 

var genders = ["male.", "female."]
var tableView = UITableView()

override init(frame: CGRect) 
    super.init(frame: frame)

    self.layer.cornerRadius = 6


required init?(coder aDecoder: NSCoder) 
    fatalError("init(coder:) has not been implemented")


override func layoutSubviews() 
    tableView.delegate = self
    tableView.dataSource = self
    self.addSubview(tableView)

    // Table View constraints
    tableView.translatesAutoresizingMaskIntoConstraints = false
    tableView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
    tableView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    tableView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true

    // Table view design
    tableView.backgroundColor = .clear
    tableView.separatorStyle = .none
    tableView.allowsSelection = true
    tableView.isUserInteractionEnabled = true


func numberOfSections(in tableView: UITableView) -> Int 
    return 1


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return 2


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = UITableViewCell()
    cell.textLabel?.text = genders[indexPath.row]
    cell.textLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
    cell.textLabel?.textColor = .white
    cell.textLabel?.textAlignment = .center
    cell.backgroundColor = .clear
    cell.selectionStyle = .none
    cell.isUserInteractionEnabled = true
    return cell


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    print(genders[indexPath.row])


在父级UITableViewController中配置下拉视图

func genderDropdownViewConfig() 
    genderDropdownView.backgroundColor = Constants.azureColor
    genderDropdownView.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
    genderDropdownView.translatesAutoresizingMaskIntoConstraints = false
    genderDropdownButton.addSubview(genderDropdownView)

    genderDropdownButton.addSubview(genderDropdownView)
    tableView.bringSubview(toFront: genderDropdownView)

    genderDropdownView.topAnchor.constraint(equalTo: genderDropdownButton.bottomAnchor).isActive = true
    genderDropdownView.centerXAnchor.constraint(equalTo: genderDropdownButton.centerXAnchor).isActive = true
    genderDropdownView.widthAnchor.constraint(equalTo: genderDropdownButton.widthAnchor).isActive = true
    //genderDropdownHeight = genderDropdownView.heightAnchor.constraint(equalToConstant: 0)
    genderDropdownHeight = genderDropdownView.heightAnchor.constraint(equalToConstant: 0)

    for subview in genderDropdownView.subviews 
        subview.backgroundColor = .clear
    


override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    let heights = [280, 130, 103, 103, 103, 103]
    if indexPath.row ==  2 && genderIsOpen == true 
        return 191
     else 
        return CGFloat(heights[indexPath.row])
    


@objc func genderDropDownTouched() 
    if genderIsOpen == false 
        NSLayoutConstraint.deactivate([self.genderDropdownHeight])
        genderDropdownHeight.constant = 88
        genderIsOpen = true
        NSLayoutConstraint.activate([self.genderDropdownHeight])

        // Editing height of cell
        tableView.reloadData()

        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: 
            self.genderDropdownView.layoutIfNeeded()
            self.genderDropdownView.center.y += self.genderDropdownView.frame.height / 2
        , completion: nil)
     else 
        NSLayoutConstraint.deactivate([self.genderDropdownHeight])
        genderDropdownHeight.constant = 0
        genderIsOpen = false
        NSLayoutConstraint.activate([self.genderDropdownHeight])

        // Editing height of cell
        tableView.reloadData()

        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: 
            self.genderDropdownView.center.y -= self.genderDropdownView.frame.height / 2
            self.genderDropdownView.layoutIfNeeded()
        , completion: nil)
    

【问题讨论】:

通常,无法响应触摸是因为视图在其父视图之外。检查是否是这种情况。 @matt - 感谢您的回复。我相信它在我的超级视图中,只是添加了另一张我相信可以证明这一点的图片 一个简单的检查方法是在 GenderDropDownView 中添加这一行:self.clipsToBounds = true。如果这导致表格视图不可见,则它位于下拉视图之外。 @matt 感谢分享这个技巧。我只是添加了行,table view 并没有变得不可见,所以它必须在superview中 仅供参考 - layoutSubviews 不是设置表格视图的数据源和委托的正确位置,也不是将表格视图添加为子视图的位置。 layoutSubviews 可以多次调用。应该在layoutSubviews 中的唯一代码是更新子视图布局的代码。您在layoutSubviews 中拥有的所有代码都应该在init 中。 【参考方案1】:

它的工作原理是下拉视图是按钮的子视图

但下拉视图出现在按钮之外。因此它超出了其父视图的范围,这意味着它无法响应触摸。

【讨论】:

刚刚启用按钮有clipsToBounds = true,它确实是不可见的。我应该添加什么下拉视图作为子视图? 到按钮的超级视图?我真的不能告诉你。我不是在设计这个应用程序。我觉得我已经回答了这个问题。谜底是为什么无法触摸表格视图,谜底就解决了。

以上是关于tableView - didSelectRowAtIndexPath 未调用的主要内容,如果未能解决你的问题,请参考以下文章

从选定索引处的表视图中的数组中删除

将数据从 didSelectRowAtIndexPath 传递到另一个视图控制器 ios7

如何使用tableview外的按钮将tableview移动到新的tableview

tableView(cellForRowAtIndexPath) 与 tableView.cellForRowAtIndexPath()?

TableView里面的tableview cell swift 3

将 tapGesture 添加到 tableView 则无法执行 tableView(_ tableView: UITableView, didSelectRowAt indexPath: Index