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

问题描述:

我在tableviewcontroller中有一个UISwitch,当开关切换时,我希望它改变我在视图控制器内创建的数组中的布尔变量的值,即该单元格与之相关。有点像IOS上的股票报警应用程序,其中每个单元格有UISwitch,并且切换开关将关闭每个单独的警报。因此,与UISwitch,其选择的代码,这是cellForRowAtIndexPath方法内部UISwitch在tableviewcell的附件视图中,使用选择器传递参数以具有选择器函数,请参阅indexpath.row?

//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 

我想要它做的这个

func switchTriggered(a: Int) { 
    changeValueOfArray = array[indexPath.row] 
} 

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

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 

让保存在数组的布尔值

func switchTriggered(sender: UISwitch) { 
     sender.on ? array[sender.tag]=1 : array[sender.tag]=0 
    } 
} 
+0

非常感谢!这很容易。 – Jolaroux

+0

如果你认为它是正确的然后请投票回答 – Bhagabata

+0

一个问题更多我知道按钮是打开还是关闭? –

的基本想法是,你可以捕捉它的开关被翻转的单元格,然后使用tableView.indexPath(for:)UITableViewCell参考转化为NSIndexPath,您可以使用它的row来确定模型结构中的哪一行需要更新。

这样做的构成要素包括:

  1. 创建捕获在表格视图中显示的信息的模型对象。例如,让我们假设每一个细胞包含Roomname和一个布尔反射光是否是:

    struct Room { 
        var name: String 
        var lightsOn: Bool 
    } 
    
  2. 然后,表视图控制器将具有那些的数组:

    var rooms: [Room]! 
    
  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) 
        } 
    
    } 
    

    我显然设置的基类的细胞原型是本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 
    } 
    
  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 
         } 
        } 
    
    } 
    

现在,我不希望你担心上述的细节。相反,尝试捕捉一些基本思路:

底线,给你直接的问题,一旦你知道哪个电池进行了更新,你可以用UITableView询问,以确定哪些NSIndexPathUITableViewCell参考对应,使用tableView.indexPath(for:)

+0

从步骤3开始,视图控制器中是那些类和协议? – Jolaroux

+0

步骤4和5是视图控制器的方法,但步骤3是单元的单独类(以及视图控制器在步骤5中遵循的协议)。 – Rob

斯威夫特3更新:

let lightSwitch = UISwitch(frame: CGRect.zero) as UISwitch 
lightSwitch.isOn = false 
lightSwitch.addTarget(self, action: #selector(switchTriggered), for: .valueChanged) 
lightSwitch.tag = indexPath.row 
cell?.accessoryView = lightSwitch