开发者

How do I maintain the selected index of UISegmentedControl inside a UITableViewCell when the cell is reloaded?

I have a custom UITableViewCell with a UISegmentedControl in it as follows: #import

@interface TFSegmentedControlCell : UITableViewCell {
    UISegmentedControl *segmentedControl;
    UILabel *questionTitle;  开发者_如何学Go   
}

@property (nonatomic, retain) UISegmentedControl *segmentedControl;
@property (nonatomic, retain) UILabel *questionTitle;

@end

I am reusing these cells for good memory management, and I can envisage situations where I'll have 100 or so cells. The segment titles are taken from an array which is loaded from online. I do this as follows:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    TFSegmentedControlCell *cell = (TFSegmentedControlCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[TFSegmentedControlCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    NSArray *segmentHeaders = [[[self.questionsArray objectAtIndex:indexPath.row] valueForKey:@"answer_labels"] componentsSeparatedByString:@","];

    for (int i=0; i<[segmentHeaders count]; i++) {
        [cell.segmentedControl insertSegmentWithTitle:[segmentHeaders objectAtIndex:i] atIndex:cell.segmentedControl.numberOfSegments animated:NO];
    }

    cell.questionTitle.text = [NSString stringWithFormat:@"%u. %@",indexPath.row + 1,[[self.questionsArray objectAtIndex:indexPath.row] valueForKey:@"description"]];

    return cell;
}

Problem is, the selected index stays with the cell not the index, ie, if I scroll down and a new cell it loaded (from off screen), it will have the selected index of the first cell (now off screen). If I select a different segment in the newly loaded cell, when I scroll back up, it will have changed the first cell's selected segment.

I'm not currently calling any methods when a segment is selected, simply iterating through all UISegmentedControls when a 'Done' button is pressed and adding all selectedSegments to an Array and sending it to an online php file for processing.

Ideas much appreciated :)


Solution:

I added int row to TFSegmentedControlCell.h

Then I added a method for when the UISegmentedControl value changes:

-(void)selectedTFSegment:(id)sender { 
    TFSegmentedControlCell *cell = (TFSegmentedControlCell *)[[sender superview] superview]; 
    [[self.questionsArray objectAtIndex:cell.row] setValue:[NSString stringWithFormat:@"%i",cell.segmentedControl.selectedSegmentIndex] forKey:@"selectedSegment"]; 
} 

And then reconfigured the initialisation of the cells:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = indexPath.row;
    static NSString *CellIdentifier = @"Cell";

    TFSegmentedControlCell *cell = (TFSegmentedControlCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[TFSegmentedControlCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    NSArray *segmentHeaders = [[[self.questionsArray objectAtIndex:row] valueForKey:@"answer_labels"] componentsSeparatedByString:@","];

    [cell.segmentedControl removeAllSegments];
    for (int i=0; i<[segmentHeaders count]; i++) {
        [cell.segmentedControl insertSegmentWithTitle:[segmentHeaders objectAtIndex:i] atIndex:cell.segmentedControl.numberOfSegments animated:NO];
    }

    cell.row = row;
    [cell.segmentedControl addTarget:self action:@selector(selectedTFSegment:) forControlEvents:UIControlEventValueChanged];

    if ([[self.questionsArray objectAtIndex:row] objectForKey:@"selectedSegment"] != nil) {
        int newIndex = [[[self.questionsArray objectAtIndex:row] objectForKey:@"selectedSegment"] intValue];
        [cell.segmentedControl setSelectedSegmentIndex:newIndex];
    } else {
        [cell.segmentedControl setSelectedSegmentIndex:UISegmentedControlNoSegment];
    }

   cell.questionTitle.text = [NSString stringWithFormat:@"%u. %@",indexPath.row + 1,[[self.questionsArray objectAtIndex:row] valueForKey:@"description"]];

    return cell;
}


Each time your tableView needs a cell it calls tableView:cellForRowAtIndexPath:. So, somewhere in that method (e.g. where you assign the question title) you need to set the selected index of your current cell's segmented control. Ideally, you could do something like this:

[cell.segmentedControl setSelectedSegmentIndex:
    [[self.questionsArray objectAtIndex:indexPath.row] valueForKey:@"selectedIndex"]];

Which implies that your objects in questionsArray need a NSInteger property selectedIndex (for example), that would reflect the value of the selected segment index for each row.


Remember, every cell inside the table view is reusable, that means, when you scroll up or down, the cells off the screen may be enqueued and removed from table view, and then added in to current view port of table view, that's also the reason why you should remember the status for specific row and configure your cell very time in the -tableView:cellForRowAtIndexPath:. So, the solution for your issue here is, when changing the segmentedControl's selected index, your should remember it, and then assign it in the -tableView:cellForRowAtIndexPath:.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜