I have a custom tablecell with some labels and images and a uisegmented control. When I load the cell into the table everything is wired properly in that the right images show up, the labels are loaded properly with correct text and the uisegment control titles are set. However when I make a selection on the uisegment control and then scroll it does not work properly. Random uisegment controls further down when you scroll show up as selected and when you scroll back the previously selected uisegs are deselected (the default).
I know it has to do with dequeing but am unsure how to fix. I think I need to save the state of the uiseg in an array and then reset when it scrolls onscreen but I am not sure how to do that.
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
User *user = nil;
NSInteger row = [indexPath row];
static NSString *CellIdentifier = @"tableCell";
static NSString *CellNib = @"tableCell";
tableCell *cell = (tableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (tableCell *)[nib objectAtIndex:0];
}
if (tableView == [[self searchDisplayController] searchResultsTableView]) {
user = [[self filteredListItems] objectAtIndex:row];
} else {
user = [[self userArrayData] objectAtIndex:row];
}
NSString *urlString = [NSString stringWithFormat: @"%@", user.icon];
NSString *urllString = [NSString stringWithFormat: @"%@", user.screen];
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:urlString]
placeholderImage:[UIImage imageNamed:@"placeholderIcon@2x.png"]];
[cell.imagedView setImageWithURL:[NSURL URLWithString:urllString]
placeholderImage:[UIImage imageNamed:@"placeholderIcon@2x.png"]];
[cell.segControl setTitle:user.name forSegmentAtIndex:0];
[cell.segControl setTitle:user.client forSegmentAtIndex:1];
//cell.segControl.selectedSegmentIndex = UISegmentedControlNoSegment;
[cell.segControl addTarget:self action:@selector(makePick:) forControlEvents:UIControlEventValueChanged];
return cell;
}
Right, it definitely has to do with the de-queuing and cells being reused. In your cellForRowAtIndexPath, you always need to reset the segmented control selected index to the last known state, which means you need a way to save the state. You could set this up in your makePick: method since you alreadh have that as a target for when the value changes.
All you would need to do is get the indexpath of the cell, and store the value of the segmented control in an NSMutableDictionary, letting the indexpath of the row be the key in the dictionary. You could read the contents from teh dictionary in the same way so that you can set the selected index of the segmented control in your cellForRowAtIndexPath.
Riddle me this, Batman. Closer still. This will not update the values and in fact crashes when I scroll back up from the bottom with the following error in the console:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
I think this is really close to updating the uisegcontrol when you scroll. Can anyone take a look? As a quick note I set up my nsmarray with 16 nsmarrays of 2 nsnumbers - one of the row and one of the segment selected like so:
This might be something. I can see in the console the array is updating but it has a different format than the original. It has an extra set of parentheses around each.
Right, the first one is just an array of 0's. The second one is an array of arrays. It sounds like you just need to initailize your home array to contain arrays of 2 integers each, rather than just a single array.
Are you going to be adding anymore cells to the tableView, i.e. are cells added dynamically by the user, or are the total number of rows set with no new rows being added? How many total rows do you have?
If you're not adding anymore rows to the tableView, or the total number of shares you anticipate the user to add will not be a large number, don't make the cells reusable. Change: