快速块选择自定义节标题单元格

时间:2018-04-28 23:25:10

标签: ios swift uitableview

我有一个带有自定义部分标题的UITableView,通过故事板使用标识符为“headerCell”的自定义原型单元格,以及一个名为“HeaderViewCell”的Cocoa Touch类,为UITableViewCell创建子类。

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerCell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! HeaderViewCell

    headerCell.sectionTitle.text = viewModel.items[section].sectionTitle
    headerCell.section = section
    headerCell.delegate = self

    return headerCell
}

单元格中的按钮会触发传递给分配给它的部分的委托func。

一切都很棒 - 设置标题,点击我需要的按钮等等...除了点击部分标题(左侧)和按钮(右侧)之间的空白区域外,标题高亮显示好像它是该部分中的一个单元格,然后对该部分的第一行执行segue。

属性检查器中的选择设置为“无”。如果我切换用户交互已启用,则该按钮不起作用。

我发现很多帖子都是人们试图在节标题上注册点击(答案:用点击手势),但是在寻找如何阻止它们时已经筋疲力尽了。在委托方法的didSelectRow中,我看到了相同的IndexPath,就像我点击了行而不是标题一样,所以我无法阻止它。

使用自定义原型单元格是对自定义节标题的最广泛建议的响应,我原本预计这对其他人也是一个问题。 ?

2 个答案:

答案 0 :(得分:1)

  

“HeaderViewCell”继承UITableViewCell。

停在那儿。那是完全错误的。您的节标题不应该是UITableViewCell。它应该是UITableViewHeaderFooterView(或其子类)。

只要您进行了更改(以及对标题视图类型注册所需的任何相应更改),您的问题就会消失。

答案 1 :(得分:0)

马特的答案应该有效。

创建UITableViewHeaderFooterView类型的子类并将其命名为 CustomHeaderView

class CustomHeaderView: UITableViewHeaderFooterView {
   // programmatically add the sectionTitle and whatever else inside here. Matt said there isn’t a storyboard or nib for a HeaderFooterView so do it programmatically
}

然后在viewForHeaderInSection里面使用tableView.dequeueReusableHeaderFooterView并将其转换为 CustomHeaderView

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    // don't forget to rename the identifier 
    let customHeaderView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "customHeaderView") as! CustomHeaderView

    customHeaderView.sectionTitle.text = viewModel.items[section].sectionTitle
    customHeaderView.section = section
    customHeaderView.delegate = self

    return customHeaderView
}

如果没有试试这个。

如果您不希望单元格突出显示,请先将选择样式设置为.none

在HeaderCell本身内设置.selectionStyle = .none

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerCell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! HeaderViewCell

    headerCell.sectionTitle.text = viewModel.items[section].sectionTitle
    headerCell.section = section
    headerCell.delegate = self
    headerCell.selectionStyle = .none // set it here

    return headerCell
}

然后在didSelectRowAtIndexPath中找出所选单元格的类型。如果它是HeaderCell,那么只有return并且单元格不应该推送。如果它是任何其他类型的单元格(例如PushCell),则那些单元格应该执行segue:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    // if it's a HeaderCell then do nothing but print
    if let _ = tableView.cellForRowAtIndexPath(indexPath) as? HeaderCell {
        tableView.deselectRow(at: indexPath, animated: true)
        print("+++++HeaderCell was tapped")
        return // nothing should happen
    }

    // if it's a PushCell then push
    if let _ = tableView.cellForRowAtIndexPath(indexPath) as? PushCell {
        print("-----PushCell was tapped")
        performSegue(withIdentifier...
        // or if your using navigationController?.pushViewController(...
    }
}