在tableviewcell的附件视图中使用UISwitch,使用选择器传递参数以使选择器函数看到indexpath.row?

Jol*_*oux 3 uitableview uiswitch ios swift swift3

我有一个UISwitchtableviewcontroller,当切换开关时,我希望它改变我在视图控制器内创建的数组中的布尔变量的值,该单元格与之相关.有点像IOS上的Stock Alarm App,每个单元都有一个UISwitch,并且切换开关将关闭每个单独的警报.因此UISwitch,使用其选择器代码,这是在cellForRowAtIndexPath方法内部

//switch
    let lightSwitch = UISwitch(frame: CGRectZero) as UISwitch
    lightSwitch.on = false
    lightSwitch.addTarget(self, action: #selector(switchTriggered), forControlEvents: .ValueChanged)
    //lightSwitch.addTarget(self, action: "switchTriggered", forControlEvents: .ValueChanged )

    cell.accessoryView = lightSwitch
Run Code Online (Sandbox Code Playgroud)

我希望它能做到这一点

func switchTriggered(a: Int) {
    changeValueOfArray = array[indexPath.row]
}
Run Code Online (Sandbox Code Playgroud)

我还没有为该部分编写的代码,但我的问题是,我如何让switchTriggered函数看到该indexPath.row值,而不将其作为参数传递给函数,因为我不能因为它的选择器?

Bha*_*ata 5

let lightSwitch = UISwitch(frame: CGRectZero) as UISwitch
    lightSwitch.on = false
    lightSwitch.addTarget(self, action: #selector(switchTriggered), forControlEvents: .ValueChanged)
    lightSwitch.tag = indexpath.row
    cell.accessoryView = lightSwitch
Run Code Online (Sandbox Code Playgroud)

让我们在Array中保存您的布尔值

    func switchTriggered(sender: UISwitch) {
      sender.on ? array[sender.tag]=1 : array[sender.tag]=0
     }
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*Rob 5

基本思想是,您可以捕获翻转开关的单元格,然后tableView.indexPath(for:)将该引用UITableViewCell转换为 a NSIndexPath,并且您可以使用其row来识别模型结构中的哪一行需要更新。

其构成要素包括:

  1. 创建一个模型对象来捕获要在表视图中显示的信息。例如,假设每个单元格都包含nameaRoom和一个反映灯是否打开的布尔值:

    struct Room {
        var name: String
        var lightsOn: Bool
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后表视图控制器将有一个数组:

    var rooms: [Room]!
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我将定义一个UITableViewCell带有标签和开关插座的子类。我还将灯开关的“值更改”连接到该单元中的方法。我还为单元设置了一个协议,以通知其表视图控制器灯开关已翻转:

    protocol RoomLightDelegate: class {
        func didFlipSwitch(for cell: UITableViewCell, value: Bool)
    }
    
    class RoomCell: UITableViewCell {
    
        weak var delegate: RoomLightDelegate?
    
        @IBOutlet weak var roomNameLabel: UILabel!
        @IBOutlet weak var lightSwitch: UISwitch!
    
        @IBAction func didChangeValue(_ sender: UISwitch) {
            delegate?.didFlipSwitch(for: self, value: sender.isOn)
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

    显然,我将单元原型的基类设置为该子类UITableViewCell,并连接@IBOutlet引用以及@IBAction用于更改开关值的引用。

  4. 然后,我让这些UITableViewDataSource方法根据属性填充单元格Room

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rooms.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SwitchCell", for: indexPath) as! RoomCell
    
        let room = rooms[indexPath.row]
    
        cell.roomNameLabel.text = room.name
        cell.lightSwitch.setOn(room.lightsOn, animated: false)
        cell.delegate = self
    
        return cell
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 请注意,上面cellForRowAtIndexPath还将其自身指定为delegate单元的 ,因此我们希望实现RoomLightDelegate协议以在翻转电灯开关时更新我们的模型:

    extension ViewController: RoomLightDelegate {
    
        func didFlipSwitch(for cell: UITableViewCell, value: Bool) {
            if let indexPath = tableView.indexPath(for: cell) {
                rooms[indexPath.row].lightsOn = value
            }
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

现在,我不想让您担心上述细节。相反,尝试捕捉一些基本想法:

最重要的是,对于您眼前的问题,一旦您知道更新了哪个单元格,您就可以使用 进行查询以UITableView确定NSIndexPathUITableViewCell引用对应的内容tableView.indexPath(for:)