提问人:Afinainflowers 提问时间:1/5/2023 更新时间:1/5/2023 访问量:278
是否可以在 Swift 中进行暴露给 Objective-C 的闭包?为界面元素制作目标是否值得?[复制]
Is it possible in Swift to make a closure that is exposed to Objective-C? And is it worth it for making targets for interface elements? [duplicate]
问:
为了提供更多上下文:我的应用程序中的屏幕有一个表格,一些表格单元格中有开关 (UISwitch)。
我想在创建每个开关的那一刻给它一个目标,如下所示:
cell.switch.addTarget(self, action: #selector({// do stuff }), for: .valueChanged)
我希望将函数制作成一个内联的选择器,因为它应该略有不同(更改数组中的不同值),具体取决于开关被翻转的行数。
问题是 - 上面的块没有编译,因为闭包没有暴露给 objective-C。我可以以某种方式在同一行中公开它吗?
我确实知道标记我的开关并为它们制作共享调用函数的选项,该函数的行为因标签而异,如下所示:
cell.switch.tag = switchNumber
cell.switch.addTarget(self, action: #selector(switchFlipped), for: .valueChanged)
@objc func switchFlipped(sender: UISwitch){
let switchNumber = sender.tag
switch(tag){
// do stuff depending on the case
}
}
但我觉得可能进行内联闭合会更快。我错了吗?
答:
2赞
HangarRash
1/5/2023
#1
简而言之,不,您不能将 Swift 闭包从 传递给 API。addTarget/selector
UIControl
您应该做的是将所有这些详细信息隐藏在自定义表视图单元格类的实现中。数据源方法甚至不应该知道单元格有开关。cellForRowAt
自定义单元格类应使自身成为开关操作的处理程序。自定义单元格类应提供回调闭包属性,当开关的值发生更改时,它会调用该属性。在 ur 中,您可以为此属性分配一个闭包。valueChanged
cellForRowAt
此设置将单元格特征的详细信息保留在单元格类中。这也使您的实现更加简洁,并且允许您使用闭包来处理自定义单元可能触发的任何事件。cellForRowAt
下面是自定义单元格类的粗略示例:
class MyCustomCell: UITableViewCell {
var actionHandler: ((MyCustomCell, Bool) -> Void)?
private var aSwitch: UISwitch!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
// setup switch in storyboard or here in code as needed
aSwitch.addTarget(self, action: #selector(switchChanged), for: .valueChanged)
}
@objc func switchChanged(_ sender: UISwitch) {
actionHandler?(self, sender.isOn)
}
}
而你的:cellForRowAt
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "someIdentifier", for: indexPath) as! MyCustomCell
cell.actionHandler = { (cell, state) in
// Do stuff
}
return cell
}
根据设置的需要调整细节。
评论
UIAction
addAction
addTarget