我面临的问题可能是对可重复使用细胞的概念缺乏了解。我要说,要创建30行,每行都有一个UISwitch。
当我切换其中一个开关时,它的行为会影响其他29个。重点是:据我所知,iOS并不会立即创建所有这些,而是等到当TableView向上和向下滚动时重用单元格。
如何保留这些重用对象的副本并告诉iOS为交换机设置正确的值?
我已经考虑将细胞附加到[UISwitch],但我无法将所有30个细胞放在那里,看看:
...
var switches = [UISwitch]()
...
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Field10Cell", for: indexPath) as! Field10TableViewCell
...
//cell.value is a UISwitch
if !switches.contains(cell.value) {
switches.append(cell.value)
}
return cell
}
答案 0 :(得分:5)
您可以创建一个存储已按下开关的单元格索引的集合。
var activeSwitches = Set<IndexPath>()
每当用户按下单元格上的开关时,您将其存储在以下集合中:
activeSwitches.insert(indexPath)
如果您需要检查交换机是否已激活,只需检查其容器单元的indexPath是否处于活动开关中,如下所示:
if activeSwitches.contains(indexPath) {
// do something
}
为了知道用户何时按下特定开关,我建议使用以下内容:
在Field10TableViewCell上创建一个协议并添加一个委托。
protocol Field10Delegate {
func didChangeSwitch(value: Bool, indexPath: IndexPath)
}
class Field10TableViewCell {
var delegate: Field10Delegate?
var indexPath: IndexPath?
@IBOutlet weak var fieldSwitch: UISwitch! // Can't use 'switch' as a variable name
@IBAction func switchValueChanged(_ sender: UISwitch) {
if let indexPath = indexPath {
delegate?.didChangeSwitch(value: sender.isOn, indexPath: indexPath)
}
}
创建单元格时,将视图控制器设置为委托
let cell = tableView.dequeueReusableCell(withIdentifier: "Field10Cell", for: indexPath) as! Field10TableViewCell
cell.delegate = self
cell.indexPath = indexPath
让您的视图控制器符合协议:
extension ViewController: Field10Delegate {
/* Whenever a switch is pressed on any cell, this delegate will
be called. This is a good place also to trigger a update to
your UI if it has to respond to switch changes.
*/
func didChangeSwitch(value: Bool, indexPath: IndexPath) {
if value {
activeSwitches.insert(indexPath)
} else {
activeSwitches.remove(indexPath)
}
updateUI()
}
}
通过上述内容,您可以随时了解哪些开关处于活动状态,您可以使用此信息处理出列单元格。