自定义 UITableViewCell 重用问题中的 UISwitch
UISwitch in custom UITableViewCell Reuse Issue
问题如下:我有一个带有自定义单元格的表格视图。该单元格包含一个标签和一个 UISwitch。我已将 label.text 值设置为一个数组,但 UISwitch 正在被重用。
示例:如果我在第一行切换开关,第 5 行将被启用,如果我滚动它会继续重复使用单元格并导致问题。
视频:https://vimeo.com/247906440
视图控制器:
class ViewController: UIViewController {
let array = ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"]
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
cell.label.text = array[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
}
自定义单元格:
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var toggleSwitch: UISwitch!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
我意识到没有代码试图存储这些数据,因为我没有成功。任何想法都会有所帮助。该项目目前使用 MVC 模型,我相信这是答案,但只需要一些帮助。
开始创建模型,例如:
struct item {
var id: String
var name: String
var isActivated: Bool
init(id: String, name: String, isActivated: Bool) {
self.id = id
self.name = name
self.isActivated = isActivated
}
}
let item1 = item(id: "1", name: "One", isActivated: false)
let item2 = ...........
let item3 = ...........
let items [item1, item2, item3]
有了它,您可以触发布尔值是否激活。
我想你也得看看https://developer.apple.com/documentation/uikit/uitableviewcell/1623223-prepareforreuse。
我建议您创建 cellViewModel class 并保留它的数组,而不仅仅是字符串。你的 cellViewModel 可能看起来像,
class CellViewModel {
let title: String
var isOn: Bool
init(withText text: String, isOn: Bool = false /* you can keep is at by default false*/) {
self.title = text
self.isOn = isOn
}
现在,构建 CellViewModel 数组
let array =["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"]
var cellViewModels = [CellViewModel]()
for text in array {
let cellViewModel = CellViewModel(withText: text)
cellViewModels.append(cellViewModel)
}
将您的 tableVieDelegate 函数更改为:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
let cellViewModel = cellViewModels[indexPath.row]
cell.label.text = cellViewModel.title
cell.toggleSwitch.isOn = cellViewModel.isOn
cell.delegate = self
return cell
}
在您的自定义单元格 class 中,添加此协议:
protocol CellActionDelegate: class {
func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell)
}
在您的自定义单元格中将代表添加为 属性,
weak var delegate: CellActionDelegate?
此外,在开关更改时,添加此行,
delegate?.didChangeSwitchStateOnCell(self)
现在,您的 viewController 应该注册并收听此委托:
我添加了行 cellForRowAtIndexPath 来注册代表。要收听此委托,请将此功能添加到您的 VC.
func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell) {
let indexPath = tableView.indexPath(for: cell)
cellViewModels[indexPath.row].isOn = cell.toggleSwitch.isOn
}
问题如下:我有一个带有自定义单元格的表格视图。该单元格包含一个标签和一个 UISwitch。我已将 label.text 值设置为一个数组,但 UISwitch 正在被重用。
示例:如果我在第一行切换开关,第 5 行将被启用,如果我滚动它会继续重复使用单元格并导致问题。
视频:https://vimeo.com/247906440
视图控制器:
class ViewController: UIViewController {
let array = ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"]
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
cell.label.text = array[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
}
自定义单元格:
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var toggleSwitch: UISwitch!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
我意识到没有代码试图存储这些数据,因为我没有成功。任何想法都会有所帮助。该项目目前使用 MVC 模型,我相信这是答案,但只需要一些帮助。
开始创建模型,例如:
struct item {
var id: String
var name: String
var isActivated: Bool
init(id: String, name: String, isActivated: Bool) {
self.id = id
self.name = name
self.isActivated = isActivated
}
}
let item1 = item(id: "1", name: "One", isActivated: false)
let item2 = ...........
let item3 = ...........
let items [item1, item2, item3]
有了它,您可以触发布尔值是否激活。
我想你也得看看https://developer.apple.com/documentation/uikit/uitableviewcell/1623223-prepareforreuse。
我建议您创建 cellViewModel class 并保留它的数组,而不仅仅是字符串。你的 cellViewModel 可能看起来像,
class CellViewModel {
let title: String
var isOn: Bool
init(withText text: String, isOn: Bool = false /* you can keep is at by default false*/) {
self.title = text
self.isOn = isOn
}
现在,构建 CellViewModel 数组
let array =["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"]
var cellViewModels = [CellViewModel]()
for text in array {
let cellViewModel = CellViewModel(withText: text)
cellViewModels.append(cellViewModel)
}
将您的 tableVieDelegate 函数更改为:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
let cellViewModel = cellViewModels[indexPath.row]
cell.label.text = cellViewModel.title
cell.toggleSwitch.isOn = cellViewModel.isOn
cell.delegate = self
return cell
}
在您的自定义单元格 class 中,添加此协议:
protocol CellActionDelegate: class {
func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell)
}
在您的自定义单元格中将代表添加为 属性,
weak var delegate: CellActionDelegate?
此外,在开关更改时,添加此行,
delegate?.didChangeSwitchStateOnCell(self)
现在,您的 viewController 应该注册并收听此委托: 我添加了行 cellForRowAtIndexPath 来注册代表。要收听此委托,请将此功能添加到您的 VC.
func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell) {
let indexPath = tableView.indexPath(for: cell)
cellViewModels[indexPath.row].isOn = cell.toggleSwitch.isOn
}