在自定义 UITableViewCell 中设置切换目标
Set target for switch in custom UITableViewCell
我有一个带有开关的自定义单元格。我想在 tableView(cellForRowAt:)
中添加目标。但是通过这样做(在示例代码中)我将创建一个强大的引用循环。
然后我尝试使用协议/委托方法,但这意味着所有单元格都将调用相同的方法。
如何设置我的单元格并相应地添加目标?
强引用循环:
class customCell: UITableViewCell {
var customSwitch: UISwitch()
// setup switch
}
class VC1: UITableViewController {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.customSwitch.addTarget(self, action: #selector(handleSwitch1), for: valueChanged)
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.customSwitch.addTarget(self, action: #selector(handleSwitch2), for: valueChanged)
return cell
default:
fatalError()
}
}
@objc func handleSwitch1(_ sender: UISwitch) { }
@objc func handleSwitch2(_ sender: UISwitch) { }
}
使用委托:
class customCell: UITableViewCell {
var customSwitch: UISwitch()
weak var delegate: VC1Delegate?
// setup switch
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
customSwitch.addTarget(self, action: #selector(handleSwitch), for: valueChanged)
}
@objc func handleSwitch(_ sender: UISwitch) {
delegate?.handleSwitch1(sender)
}
}
protocol VC1Delegate: class {
func handleSwitch1(_ sender: UISwitch)
func handleSwitch2(_ sender: UISwitch)
}
class VC1: UITableViewController, VC1Delegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.delegate = self
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.delegate = self
return cell
default:
fatalError()
}
}
@objc func handleSwitch1(_ sender: UISwitch) { }
@objc func handleSwitch2(_ sender: UISwitch) { }
}
在您标记为 "Strong reference cycle" 的代码中没有强引用循环,因此请继续使用它。
你以为强引用循环在哪里?是把self
当成target
吗? docs 明确地说:
The control does not retain the object in the target parameter
这是意料之中的事情。如果您不能将 self
设置为控件的操作目标,我们都会陷入困境。
我有一个带有开关的自定义单元格。我想在 tableView(cellForRowAt:)
中添加目标。但是通过这样做(在示例代码中)我将创建一个强大的引用循环。
然后我尝试使用协议/委托方法,但这意味着所有单元格都将调用相同的方法。
如何设置我的单元格并相应地添加目标?
强引用循环:
class customCell: UITableViewCell {
var customSwitch: UISwitch()
// setup switch
}
class VC1: UITableViewController {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.customSwitch.addTarget(self, action: #selector(handleSwitch1), for: valueChanged)
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.customSwitch.addTarget(self, action: #selector(handleSwitch2), for: valueChanged)
return cell
default:
fatalError()
}
}
@objc func handleSwitch1(_ sender: UISwitch) { }
@objc func handleSwitch2(_ sender: UISwitch) { }
}
使用委托:
class customCell: UITableViewCell {
var customSwitch: UISwitch()
weak var delegate: VC1Delegate?
// setup switch
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
customSwitch.addTarget(self, action: #selector(handleSwitch), for: valueChanged)
}
@objc func handleSwitch(_ sender: UISwitch) {
delegate?.handleSwitch1(sender)
}
}
protocol VC1Delegate: class {
func handleSwitch1(_ sender: UISwitch)
func handleSwitch2(_ sender: UISwitch)
}
class VC1: UITableViewController, VC1Delegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.delegate = self
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomCell
cell.delegate = self
return cell
default:
fatalError()
}
}
@objc func handleSwitch1(_ sender: UISwitch) { }
@objc func handleSwitch2(_ sender: UISwitch) { }
}
在您标记为 "Strong reference cycle" 的代码中没有强引用循环,因此请继续使用它。
你以为强引用循环在哪里?是把self
当成target
吗? docs 明确地说:
The control does not retain the object in the target parameter
这是意料之中的事情。如果您不能将 self
设置为控件的操作目标,我们都会陷入困境。