我有一个包含UISwitch和UILabel的自定义UITableViewCell。当轻触开关时,我想知道哪个单元的开关已被激活/停用。
我的cellForRowAtIndexPathMethod中有以下代码,用于将目标添加到我的单元格的UISwitch中:
[cell.notifSwitch addTarget:self action:@selector(switchChangedFromCell:) forControlEvents:UIControlEventValueChanged];
以下是选择器的代码:
- (void)switchChangedFromCell:(id)sender {
HydrationNotificationTableViewCell *cell = (HydrationNotificationTableViewCell *)sender;
if ([cell.notifSwitch isOn]) {
NSLog(@"Notification for %@ has been activated", cell.notifLabel.text);
}
else {
NSLog(@"Deactivated notification %@", cell.notifLabel.text);
}
}
马上就认为我把发送者当作一个单元格是错误的,因为发送者真的是来自单元格的UISwitch。我想知道我如何能够自己通过细胞,所以我知道哪个细胞已被改变。
一种解决方案是在我的cellForRowAtIndexPath方法中为每个UISwitch设置一个不同的标签,但我想知道是否有更清洁的解决方案。
答案 0 :(得分:4)
坏消息是你不能那样做......确切地说。
好消息是,在您的IBAction中,UISwitch
是发件人,您可以使用它来确定哪个单元格包含UISwitch
。
我在Github上有一个名为TableViewExtension的项目,它展示了如何做到这一点。
唯一真正的技巧是UITableView的扩展:
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
}
}
如果您添加该扩展程序,则可以让您的IBAction使用发件人来确定哪个控件触发了点击,并调用该方法来确定哪个单元格包含该控件:
@IBAction func controllTriggered(_ sender: UISwitch) {
guard let indexPath = tableView.indexPathForView(sender) else { return }
//Now you have the indexPath of the cell containing `sender`
}
请注意,在您的代码中,您尝试获取单元格,然后查询单元格的不同子视图以获取状态数据。不要那样做。您应该将状态数据存储在模型对象中。该单元用于显示信息并与用户交互。
如果用户点击一个开关,IBAction将把该开关作为它的发送者参数。您可以从发件人处获取Switch的值。
答案 1 :(得分:0)
我相信你只能通过这样的选择器方法传递发件人。
您可以考虑将UISwitch方法放在自定义UITableViewCell类中,并为自定义类创建一个委托协议,将该单元传递给ViewController。
答案 2 :(得分:0)
我提出了另一个解决方案,但这也有点难看。我将单元格转换为发送者的超级视图的超级视图(UISwitch>>内容视图>>单元格)
HydrationNotificationTableViewCell *cell = (HydrationNotificationTableViewCell *)([senderSwitch superview].superview);
希望那里有一个更清洁的解决方案。