表格视图行中的UISwitch

时间:2018-10-06 12:34:16

标签: ios swift uitableview uiswitch

在下面的代码中,我在表中填充了一些数据。开关不需要关闭。在情节提要中,我将其定义为“开”。

单元格:

var switchHandler: ((Bool)->Void)?

@IBAction func switchChanged(_ sender: UISwitch) {
    self.switchHandler?(sender.isOn)
}

视图控制器:

var selectedCells = Set<IndexPath>()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "SmsCell") as? SmsTableViewCell

    cell?.PhonNumberLbl.text = data![indexPath.section].contacts[indexPath.row]?.phoneNumber
    cell?.NameLbl.text = data![indexPath.section].contacts[indexPath.row]?.name
    cell?.selectedTF.isOn = (data![indexPath.section].contacts[indexPath.row]?.selected)!

    cell?.selectedTF.isOn = self.selectedCells.contains(indexPath)
    cell?.switchHandler = { (switchState) in
        if switchState {
            self.selectedCells.insert(indexPath)
        } else {
            self.selectedCells.remove(indexPath)
        }
    }

    return cell!
}

型号:

typealias smsModelList = [SmsModel]

struct SmsModel:Codable {
    var unitNo:Int?
    var unitPlaque:String?
    var billText:String?
    var contacts:[ContactsModel?]
}

typealias contactlistmodel = [ContactsModel]

struct ContactsModel:Codable
{
    var id :Int?
    var selected :Bool?
    var phoneNumber : String?
    var name : String?
}

有人看到错误的东西会关闭开关吗?

2 个答案:

答案 0 :(得分:0)

您同时使用

cell?.selectedTF.isOn = (data![indexPath.section].contacts[indexPath.row]?.selected)! 
cell?.selectedTF.isOn = self.selectedCells.contains(indexPath)

所以开关的isOn属性是从2个侧面控制的,因此您必须确定应该对哪条线进行补偿,而且不要依赖情节提要板原型单元设置,因为单元可以重复使用更改了,如果要默认将它们全部启用,则将var selectedCells更改为包含所有可能的indexPath并注释另一个

答案 1 :(得分:0)

首先,无论如何您都要强制打开单元格,在dequeue行中进行操作,以避免不必要的问号,并使用API​​返回非可选单元格

let cell = tableView.dequeueReusableCell(withIdentifier: "SmsCell", for: IndexPath) as! SmsTableViewCell

要解决您的问题,请直接更新selected结构的ContactsModel属性,而忽略多余的selectedCells数组。进一步声明-至少-selected为非可选,实际上没有 be 状态。并且还将所有数据源数组(data / contacts)声明为非可选的,cellForRow仅在默认indexPath上默认有一个项目时才被调用。

struct ContactsModel : Codable {
   ...
   var selected : Bool
   ...
}

...

let cell = tableView.dequeueReusableCell(withIdentifier: "SmsCell", for: IndexPath) as! SmsTableViewCell
let contact = data[indexPath.section].contacts[indexPath.row]
cell.PhonNumberLbl.text = contact.phoneNumber
cell.NameLbl.text = contact.name
cell.selectedTF.isOn = contact.selected

cell.switchHandler = { [unowned self] switchState in
    // as the structs are value types you have to specify the full reference to the data source array
    self.data[indexPath.section].contacts[indexPath.row].selected = switchState
}

在这种情况下,考虑使用类而不是结构,则可以缩短结束时间

cell.switchHandler = { switchState in
    contact.selected = switchState
}