问题
I'm using a UISwitch in the accessoryView of a UITableViewCell.
The switch uses target-action to communicate when it has been selected or deselected:
switchV.addTarget(self, action: "onChangeSwitch:", forControlEvents: UIControlEvents.ValueChanged)
The problem is figuring out which switch was selected. I know of 3 methods. Each is unsatisfying somewhow.
1. I can use tags:
switchV.tag = indexPath.row
But this sucks if you have sections (and I do), because I need to parse it into and out of a two-number section/row format.
2. I could use the data model and store the switch view on the data item that the cell is drawing:
dataItem.switch.addTarget(self, action: "onChangeSwitch:", forControlEvents: UIControlEvents.ValueChanged)
cell.accessoryView = dataItem.switch
I can then identify which switch was selected by looping over my data set and doing an identity match with sender. This is a lot of looping, and I don't want to put views in my data model.
3. Then there's this method that uses the coordinate of the switch to find the row. Stateless-ish, involves no string parsing or data model muddying, but coordinates, rly? Can I trust it?
tableView.indexPathForRowAtPoint(
sender.convertPoint(CGPointZero, toView: tableView)
)
Is there a better way to get the indexPath of the UISwitch that is selected?
回答1:
Method #3 is pretty good in my opinion. However if you want it to be really clean here's what I would do .
Declare a custom TableviewCell say CustomTableViewCell and have a delegate protocol called CustomCellDelegate. Here the delegate gets informed like so :
-(void)switchChanged:(UISwitch*)switch inCell:(CustomTableViewCell*)cell
In cellForRowAtIndexPath set your view controller as the delegate of the cell.
Add the switch to to your custom cell and make the cell as the target and implement the switch's action method. Inside the action method call the delegate :
-(void)switchChanged:(id)sender { if(self.delegate && [self.delegate respondsToSelector:@selector(switchChanged:inCell:])) { [self.delegate switchChanged:sender inCell:self]; }
Now in your viewController use the passed in cell in the delegate method to calculate the index path :
-(void)switchChanged:(id)sender inCell:(CustomTableViewCell*)cell { NSIndexPath *path = [self.tableview indexPathForCell:cell]; }
Its a bit of work but if you want to do it the proper way , you can .
回答2:
Another option is to use an hash which maintains the switch -> data link
var switchToData=[UISwitch:yourData]()
in cellForRowAtIndexPath:
switchToData[newSwitch]=myData
in onChangeSwitch
dataChanged=switchToData[switchChanged]
The hash will be quite small, the same size of the visible switch....
来源:https://stackoverflow.com/questions/32247254/uiswitch-in-table-cell-determine-selected-indexpath