如何从UITableViewCell中的Switch捕获事件?

时间:2017-05-03 21:37:25

标签: ios swift uitableview events switch-statement

在Xcode 8.3.2 Swift 3.1中,我有一个UITableView,其中每一行都包含一个标签和一个开关。我可以将交换机作为一个组进行管理(处理数组),但我真正想要的是在其中一个交换机发生更改时,在父UIViewController中触发ValueChanged事件,指示哪一行发生了更改。但是,由于Switch位于UITableViewCell中,我不确定如何将事件中继到父UIViewController。感谢。

1 个答案:

答案 0 :(得分:3)

有各种解决方案。

一种是设置UITableView的自定义子类,其中交换机链接到单元格。然后将单元格设置为具有委托属性,并在用户点击开关时让单元格向其委托发送消息。

另一种选择是在单元格的开关上设置目标/操作,以便在cellForRow(at:)方法中调用视图控制器中的方法。但是,您需要在界面构建器中将操作留空,并使用控件的allTargets属性来检查开关(或按钮或其他UIControl)是否已有目标/操作。 (如果您每次在cellForRow(at:)盲目添加目标/操作时,最终会有多个目标/操作,每次一个单元格都会被回收。

第三个选项是设置控件的自定义子类(在本例中为UISwitch),该子类具有一个在触发操作时调用的闭包属性。你将这样的控件设置为目标,如果不是n,则使动作调用闭包。然后,您的cellForRow(at:)方法可以安装一个自定义闭包,它可以在触发控件时执行任何操作。

请注意,无论您使用哪种方法,都需要一种方法来确定哪个indexPath代表交换机的值已更改。

在我对this SO question的回答中,我概述了一种通用的方法来确定哪个单元格包含视图。它可以确定哪个单元格包含用户在您的案例中点击的开关。 我概述了UI的简单扩展

它的要点是,您可以创建一个简单的UITableView扩展,让您找出包含任何IndexPath的单元格的UIView代码如下所示:< / p>

public extension UITableView {

  /**
  This method returns the indexPath of the cell that contains the specified view
   - Parameter view: The view to find.
   - Returns: The indexPath of the cell containing the view, or nil if it can't be found
  */

  func indexPathForView(_ view: UIView) -> IndexPath? {
    let origin = view.bounds.origin
    let viewOrigin = self.convert(origin, from: view)
    let indexPath = self.indexPathForRow(at: viewOrigin)
    return indexPath
  }
}