首页 > 解决方案 > 如何将原型单元格中的 UISwitch 状态传递回 UITableView

问题描述

我在原型单元格中有一个 UISwitch,我不知道如何将状态传递回我的 UITableView。我需要传回的开关状态来更新对象以反映新状态。

我尝试了以下问题,但它们都在 Objective C 中(我几乎不会写 Swift,所以我正在努力解决如何适应它们) 在原型单元中访问 UISwitch以及 如何在我的每个 UITableView 单元中检索 UISwitch 状态?

我目前正在尝试使解决方案正常工作。

以下是在 UITabelView 中构建单元的参数:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProgrammeToggleTableViewCell", for: indexPath) as? ProgrammeToogleTableViewCell else { return UITableViewCell() }

        cell.setTitle(text: programmes[indexPath.row].name)

        cell.programmeToggle.tag = indexPath.row
        print(cell.programmeToggle.tag)
        cell.programmeToggle.isOn = programmes[indexPath.row].active
        cell.programmeToggle.addTarget(self, action: #selector(ProgrammeTableViewController.switchAtValueChanged(programmeToggle: UISwitch, indexPath: IndexPath)), for: UIControl.Event.valueChanged)

        return cell
    }

我稍后尝试使用以下方法访问交换机:

    @objc func switchAtValueChanged(programmeToggle: UISwitch, indexPath: IndexPath) {

        if programmeToggle.tag == 1 {
            var programmes[indexPath.row].active = UISwitch.isOn
            print(programmes[1].active)
        }
    }

programmes是一个对象数组。

该行var programmes[indexPath.row].active = UISwitch.isOn目前给我以下错误: Consecutive statements on a line must be separated by ';' Type annotation missing in pattern Value of type '[Int]' has no member 'active'

我想使用开关的状态来编辑programmes数组中一个对象的值。由于我对 Swift 没有经验,我不知道我是在叫错树还是在工作时这是一个可行的解决方案。

感谢您的帮助,如果需要,很乐意提供任何进一步的信息。

标签: iosswiftuiswitch

解决方案


它并不像您尝试的那样微不足道。当您将表格视图单元格出列时,这意味着它将创建一个新单元格或重用一个旧单元格。例如,您有 100 个单元格,但同时只能看到 10 个。当用户向下滚动时,第一个单元格消失,然后作为第 11 个单元格重新使用。所以这在物理上是同一个细胞。并调用在其开关上添加目标选择器意味着您现在在该开关上有 2 个操作。但是正如您可能发现的那样,无论如何在这种情况下您还有其他问题(例如无法将索引路径注入方法)。

您只需要使用表作为数据的表示。所以你必须在别处修改数据。

在您的情况下,最简单的解决方案是将您的类添加到单元格本身中。只需将其分配给行方法的单元格:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProgrammeToggleTableViewCell", for: indexPath) as? ProgrammeToogleTableViewCell else { return UITableViewCell() }
    cell.programme = programmes[indexPath.row]
    return cell
}

现在将所有逻辑放在单元格中,例如:

var programme: Programme? {
    didSet {
        refresh()
    }
}
func refresh() {
    guard let programme = programme else { return }
    programmeToggle.isOn = programme.active
}

@IBAction private func switchToggled() {
    self.programme?.active = programmeToggle.isOn
}

现在,开关的动作会影响分配的程序。在你的情况下,这应该足够了。

作为替代方案,您在许多情况下需要使用委托。您的视图控制器将定义一个开关已切换的协议,并将其分配给您的单元格:

cell.progremmeID = progremme.id
cell.delegate = self
return cell

然后是协议:

func programmeCell(_ sender: ProgrammeToogleTableViewCell, didToggleProgremme programmeID: String, toActive flag: Bool) {
    programmes.first(where: { $0.id == programmeID })?.active = flag
}

推荐阅读