Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/118.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 自定义UITableViewCell重用问题中的UISwitch_Ios_Swift_Uitableview_Uiswitch - Fatal编程技术网

Ios 自定义UITableViewCell重用问题中的UISwitch

Ios 自定义UITableViewCell重用问题中的UISwitch,ios,swift,uitableview,uiswitch,Ios,Swift,Uitableview,Uiswitch,问题如下:我有一个带有自定义单元格的tableview。该单元格包含一个标签和一个UISwitch。我已将label.text值设置为数组,但UISwitch正在被重用 示例:如果我切换第一行中的开关,第五行将被启用,如果我滚动,它将继续重用单元格并导致问题 视频: 视图控制器: class ViewController: UIViewController { let array = ["One","Two","Three","Four","Five","Six","Seven","E

问题如下:我有一个带有自定义单元格的tableview。该单元格包含一个标签和一个UISwitch。我已将label.text值设置为数组,但UISwitch正在被重用

示例:如果我切换第一行中的开关,第五行将被启用,如果我滚动,它将继续重用单元格并导致问题

视频:

视图控制器:

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]
有了它,你可以触发布尔值,如果它被激活或没有


您还必须查看我的想法。

开始创建模型,例如:

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]
有了它,你可以触发布尔值,如果它被激活或没有


我想您还需要看看。我建议您创建cellViewModel类,并保留它的数组,而不仅仅是字符串。您的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
}
在自定义单元格类中,添加以下协议:

protocol CellActionDelegate: class {
    func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell)
}
在自定义单元格中添加委托作为属性

weak var delegate: CellActionDelegate?
另外,在开关更改时,添加此行

delegate?.didChangeSwitchStateOnCell(self)
现在,您的viewController应该注册并侦听此委托: 我添加了行CellForRowatineXpath以注册代表。要侦听此委托,请在VC中添加此函数

func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell) {
    let indexPath = tableView.indexPath(for: cell)
    cellViewModels[indexPath.row].isOn = cell.toggleSwitch.isOn
}

我建议您创建cellViewModel类并保留它的数组,而不仅仅是字符串。您的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
}
在自定义单元格类中,添加以下协议:

protocol CellActionDelegate: class {
    func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell)
}
在自定义单元格中添加委托作为属性

weak var delegate: CellActionDelegate?
另外,在开关更改时,添加此行

delegate?.didChangeSwitchStateOnCell(self)
现在,您的viewController应该注册并侦听此委托: 我添加了行CellForRowatineXpath以注册代表。要侦听此委托,请在VC中添加此函数

func didChangeSwitchStateOnCell(_ cell: CustomTableViewCell) {
    let indexPath = tableView.indexPath(for: cell)
    cellViewModels[indexPath.row].isOn = cell.toggleSwitch.isOn
}

在哪里保存
切换开关的开/关状态?由于它可以在您滚动
UITableView
时重复使用,因此我建议您不要依赖任何
IBOutlet
。您应该实现一个用于存储信息的模型,然后使用该模型注入所需的UI。您将
切换开关的开/关状态保存在哪里?由于它可以在您滚动
UITableView
时重复使用,因此我建议您不要依赖任何
IBOutlet
。您应该实现一个用于存储信息的模型,然后使用该模型来注入所需的UI。这会像将isOn布尔值指定为true的开关的IBOutlet那样简单吗?不管怎样,你可以把那部分加到你的答案里吗?非常感谢!你的手机会监听开关动作。您需要将此更改委托给VC。当然让我为您添加它。这会像从开关将isOn布尔值指定为true的IBOutlet一样简单吗?不管怎样,你可以把那部分加到你的答案里吗?非常感谢!你的手机会监听开关动作。您需要将此更改委托给VC。当然这是一个很好的答案,但我将使用Makund的,因为它坚持我项目其余部分的MVC模型。非常感谢您的帮助:)这是一个很好的答案,但我将使用Makund的,因为它坚持我项目其余部分的MVC模型。非常感谢您的帮助:)