如何将原型单元格中的 UISwitch 状态传回 UITableView
How to pass state of UISwitch in prototype cell back to UITableView
我在原型单元格中有一个 UISwitch,我不知道如何将状态传回我的 UITableView。我需要传回的开关状态来更新对象以反映新状态。
我尝试了以下问题,但它们都在 Objective C 中(我几乎不会写 Swift 所以我正在努力研究如何适应它们)
Access UISwitch in Prototype Cell 和
我目前正在尝试让 this 解决方案正常工作。
这是在 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 没有经验,我不知道我是不是找错了树,或者这在工作时是否是一个可行的解决方案。
感谢您的帮助,如果需要,很乐意提供任何进一步的信息。
它并不像您尝试的那么简单。当您将 table 视图单元格出队时,这意味着它将创建一个新单元格或重用旧单元格。例如,您有 100 个单元格,但同时只能看到 10 个。当用户向下滚动时,第一个单元格消失,然后它被重新用作第 11 个单元格。所以这在物理上是同一个细胞。并调用在其开关上添加目标选择器,这意味着您现在在该开关上有 2 个操作。但是正如您可能发现的那样,无论如何在这种情况下您还有其他问题(例如无法将索引路径注入方法)。
您只需要使用 table 作为数据表示。所以你必须在别处修改数据。
在您的情况下,最简单的解决方案是将 class 添加到单元格本身。只需在行方法的单元格中分配它:
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: { [=13=].id == programmeID })?.active = flag
}
首先,您需要在 table 视图单元格中创建回调。
class ProgrammeToogleTableViewCell: UITableViewCell {
@IBOutlet weak var switchUI: UISwitch!
// callback to get action of switch status
var callBackSwitchState:((Bool) -> (Void))?
// Create action for value change event on switch
@IBAction func switchAtValueChanged(programmeToggle: UISwitch) {
callBackSwitchState?(programmeToggle.isOn)
}
}
现在,在您的 cellForRowAt 数据源方法中,您需要为刚刚创建的回调设置值以获取开关状态:
在您的 table 视图中 class:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"ProgrammeToggleTableViewCell", for: indexPath) as? ProgrammeToogleTableViewCell
else { return UITableViewCell() }
cell.tag = indexPath.row
// Implement the callback to get the status of switch:
cell.callBackSwitchState = { isOn in
print("Your Switch status = \(isOn)")
// isOn is your switch status. You can update your object here.
}
// Your other code here ....
return cell
}
只需删除以下行的 var-
var 程序[indexPath.row].active = UISwitch.isOn
我在原型单元格中有一个 UISwitch,我不知道如何将状态传回我的 UITableView。我需要传回的开关状态来更新对象以反映新状态。
我尝试了以下问题,但它们都在 Objective C 中(我几乎不会写 Swift 所以我正在努力研究如何适应它们)
Access UISwitch in Prototype Cell 和
我目前正在尝试让 this 解决方案正常工作。
这是在 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 没有经验,我不知道我是不是找错了树,或者这在工作时是否是一个可行的解决方案。
感谢您的帮助,如果需要,很乐意提供任何进一步的信息。
它并不像您尝试的那么简单。当您将 table 视图单元格出队时,这意味着它将创建一个新单元格或重用旧单元格。例如,您有 100 个单元格,但同时只能看到 10 个。当用户向下滚动时,第一个单元格消失,然后它被重新用作第 11 个单元格。所以这在物理上是同一个细胞。并调用在其开关上添加目标选择器,这意味着您现在在该开关上有 2 个操作。但是正如您可能发现的那样,无论如何在这种情况下您还有其他问题(例如无法将索引路径注入方法)。
您只需要使用 table 作为数据表示。所以你必须在别处修改数据。
在您的情况下,最简单的解决方案是将 class 添加到单元格本身。只需在行方法的单元格中分配它:
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: { [=13=].id == programmeID })?.active = flag
}
首先,您需要在 table 视图单元格中创建回调。
class ProgrammeToogleTableViewCell: UITableViewCell {
@IBOutlet weak var switchUI: UISwitch!
// callback to get action of switch status
var callBackSwitchState:((Bool) -> (Void))?
// Create action for value change event on switch
@IBAction func switchAtValueChanged(programmeToggle: UISwitch) {
callBackSwitchState?(programmeToggle.isOn)
}
}
现在,在您的 cellForRowAt 数据源方法中,您需要为刚刚创建的回调设置值以获取开关状态:
在您的 table 视图中 class:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"ProgrammeToggleTableViewCell", for: indexPath) as? ProgrammeToogleTableViewCell
else { return UITableViewCell() }
cell.tag = indexPath.row
// Implement the callback to get the status of switch:
cell.callBackSwitchState = { isOn in
print("Your Switch status = \(isOn)")
// isOn is your switch status. You can update your object here.
}
// Your other code here ....
return cell
}
只需删除以下行的 var-
var 程序[indexPath.row].active = UISwitch.isOn