对此有多种解决方案。
一种是设置一个自定义的 UITableView 子类,其中开关链接到单元格。然后将单元格设置为具有委托属性,并在用户点击开关时使单元格向其委托人发送消息。
另一个选项是在单元格的开关上设置目标/操作,以在 cellForRow(at:) 方法中调用视图控制器中的方法。但是,您需要在界面生成器中将操作留空,并使用控件的 allTargets 属性来检查开关(或按钮或其他 UIControl)是否已经具有目标/操作。 (如果您每次在 cellForRow(at:) 中盲目地添加一个目标/动作,您最终会得到多个目标/动作,每次一个单元格被回收时都会有一个。
第三个选项是设置您的控件的自定义子类(在本例中为 UISwitch),该子类具有一个闭包属性,当其动作被触发时会调用该闭包属性。如果 is 不为零,您可以将这样的控件设置为目标并让操作调用闭包。然后,您的 cellForRow(at:) 方法可以安装一个自定义闭包,该闭包在触发控件时执行您想要的任何操作。
请注意,无论您使用哪种方法,您都需要一种方法来确定哪个 indexPath 代表值更改的开关。
在我对this SO question 的回答中,我概述了一种通用方法来确定哪个单元格包含视图。它可以确定哪个单元格包含用户在您的案例中点击的开关。
我概述了对UITableView 的简单扩展,它可以让您找出哪个IndexPath(如果有)包含特定的UIView。
它的要点是,您可以为UITableView 创建一个简单的扩展,让您找出包含任何UIView 的单元格的IndexPath 代码如下所示:
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
}
}