开发者

Identifying UISegmentedControl embedded in custom UITableViewCell when calling selector

I've a custom UITableViewCell which has a UISegmentedControl added as a subview via the cell's contentView property as follows:

#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;
}

What I need to be able to do is somewhat set the addTarget selector for each segmented control so that it identifies the row in question, an obvious solution being to use the segmented control's tag. However as you can see I'm already using the tag to retrieve the control from within the custom cell's contentView if an existing cell is returned via the UITableView's dequeueReusableCellWithIdentifier: method.

As such, I'm just wondering what the best way to achieve this? (I presume I could simply extend the UISegmentedControl class to add an associatedTableRow property, but I'm wondering if there's a more elegant solution.)


Because subclassing is always the worst choice I would do the superview superview dance.

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

since iOS7 changed the view hierarchy the above code won't work. You will need to use indexPathForRowAtPoint::

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


Make a subclass of UITableViewCell that has a reference to the UISegmentedControl as a property and instantiate that instead of UITableViewCell. Then you don't need the tag to refer to the segmented control and you can use it to hold the row number.

However, you could also put the row number in that subclass as a property, or even make the subclass handle the target-action. In any case, making a subclass gives you greater flexibility to handle this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜