在调用选择器时识别嵌入在自定义UITableViewCell中的UISegmentedControl

时间:2011-03-13 17:55:10

标签: iphone ios uitableview uisegmentedcontrol

我有一个自定义UITableViewCell,它通过单元格的contentView属性添加了一个UISegmentedControl作为子视图,如下所示:

#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属性,但我想知道是否有更优雅的解决方案。)

2 个答案:

答案 0 :(得分:5)

因为子类化总是最糟糕的选择,所以我会做superview superview dance。

- (IBAction)controlChanged:(UIControl *)sender
    NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
    // do something
}

由于iOS7更改了视图层次结构,因此上述代码无效。您需要使用indexPathForRowAtPoint:

- (IBAction)controlChanged:(UIControl *)sender {
    CGPoint senderOriginInTableView = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:senderOriginInTableView];
    // do something
}

答案 1 :(得分:4)

创建UITableViewCell的子类,该子类具有对UISegmentedControl的引用作为属性,并实例化而不是UITableViewCell。然后,您不需要标记来引用分段控件,您可以使用它来保存行号。

但是,您也可以将该子类中的行号作为属性,或者甚至使子类处理目标操作。无论如何,创建子类可以更灵活地处理这个问题。