Iphone 调用选择器时识别嵌入在自定义UITableViewCell中的UISegmentedControl
我有一个自定义UITableViewCell,它通过单元格的contentView属性将UISegmentedControl添加为子视图,如下所示:Iphone 调用选择器时识别嵌入在自定义UITableViewCell中的UISegmentedControl,iphone,ios,uitableview,uisegmentedcontrol,Iphone,Ios,Uitableview,Uisegmentedcontrol,我有一个自定义UITableViewCell,它通过单元格的contentView属性将UISegmentedControl添加为子视图,如下所示: #define TABLECELL_SEGMENT_TAG 1 ... - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UISegmentedControl *testSe
#define TABLECELL_SEGMENT_TAG 1
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UISegmentedControl *testSegmentedControl;
// Check for a reusable cell first, use that if it exists
UITableViewCell *tableCell = [tableView dequeueReusableCellWithIdentifier:@"OurCustomCell"];
// If there is no reusable cell of this type, create a new one
if (!tableCell) {
tableCell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:@"OurCustomCell"] autorelease];
// Create our segmented control
NSArray *segmentItems = [NSArray arrayWithObjects:@"Option 1", @"Option 2", nil];
UISegmentedControl *testSegmentedControl = [[UISegmentedControl alloc] initWithItems:segmentItems];
[testSegmentedControl setTag:TABLECELL_SEGMENT_TAG];
[[tableCell contentView] addSubview:testSegmentedControl];
[testSegmentedControl release];
}
// Set the selected segment status as required
testSegmentedControl = (UISegmentedControl *)[tableCell.contentView viewWithTag:TABLECELL_SEGMENT_TAG];
...
[testSegmentedControl addTarget:self
action:@selector(segmentedControlUpdated:)
forControlEvents:UIControlEventValueChanged];
return tableCell;
}
我需要能够做的是为每个分段控件设置addTarget
选择器,以便它识别所讨论的行,一个明显的解决方案是使用分段控件的标记。但是,您可以看到,如果通过UITableView的dequeueReusableCellWithIdentifier:
方法返回现有单元格,则我已经在使用标记从自定义单元格的contentView中检索控件
因此,我只是想知道实现这一目标的最佳方式是什么?(我想我可以简单地扩展UISegmentedControl类来添加一个
associatedTableRow
属性,但我想知道是否有更优雅的解决方案。)创建一个UITableViewCell的子类,该子类引用UISegmentedControl作为属性,并实例化它而不是UITableViewCell。然后,您不需要标记来引用分段控件,您可以使用它来保存行号
但是,您也可以将行号作为属性放在该子类中,甚至可以让该子类处理目标操作。在任何情况下,创建一个子类都可以让您更灵活地处理此问题。创建一个UITableViewCell的子类,该子类引用UISegmentedControl作为属性,并实例化该子类而不是UITableViewCell。然后,您不需要标记来引用分段控件,您可以使用它来保存行号
但是,您也可以将行号作为属性放在该子类中,甚至可以让该子类处理目标操作。在任何情况下,创建一个子类都会给你更大的灵活性来处理这个问题。因为子类化总是我做superview舞蹈时最糟糕的选择
- (IBAction)controlChanged:(UIControl *)sender
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
// do something
}
由于iOS7更改了视图层次结构,上述代码将无法工作。您需要使用InExpathForRowatPoint:
:
- (IBAction)controlChanged:(UIControl *)sender {
CGPoint senderOriginInTableView = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:senderOriginInTableView];
// do something
}
因为子类化总是最糟糕的选择,我会跳superview舞
- (IBAction)controlChanged:(UIControl *)sender
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
// do something
}
由于iOS7更改了视图层次结构,上述代码将无法工作。您需要使用InExpathForRowatPoint:
:
- (IBAction)controlChanged:(UIControl *)sender {
CGPoint senderOriginInTableView = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:senderOriginInTableView];
// do something
}
+1子类化始终是表视图单元格自定义的选择方法。+1子类化始终是表视图单元格自定义的选择方法。有点离题:为什么不将addTarget调用移到if(!tableCell)语句中?在您的代码中,每次调用CellForRowatingIndexPath时,即每次在屏幕上滚动单元格时,事件都会被连接。@hennes它当前在单元格构造函数if语句之外,因为我认为可能有一种自定义setTarget选择器的方法。也就是说,我将根据答案的建议,根据需要搬回去等。:-)有点离题:为什么不将addTarget调用移到if(!tableCell)语句中?在您的代码中,每次调用CellForRowatingIndexPath时,即每次在屏幕上滚动单元格时,事件都会被连接。@hennes它当前在单元格构造函数if语句之外,因为我认为可能有一种自定义setTarget选择器的方法。也就是说,我将根据答案的建议,根据需要搬回去等。:-)+1一个简洁的解决方案。也就是说,我怀疑对于一个非同寻常的案例(在这个案例中,有相当多的细胞定制正在进行),子分类可能是一个更简洁的解决方案,或者你是否相信呢?在我看到Matthias的答案之前,这是一个不会消失的痛苦。使用触摸检测的传统技术不适用于分段控制,因此这非常有用!好。实际上,这在iOS7上不应该起作用。事实证明,走更高层的道路并不是最好的主意。所以要小心。我用一种应该始终有效的方法更新了答案。+1一个简洁的解决方案。也就是说,我怀疑对于一个非同寻常的案例(在这个案例中,有相当多的细胞定制正在进行),子分类可能是一个更简洁的解决方案,或者你是否相信呢?在我看到Matthias的答案之前,这是一个不会消失的痛苦。使用触摸检测的传统技术不适用于分段控制,因此这非常有用!好。实际上,这在iOS7上不应该起作用。事实证明,走更高层的道路并不是最好的主意。所以要小心。我用一种应该一直有效的方法更新了答案。