Terrance Shaw
Terrance Shaw

Reputation: 161

UIScrollView in UITableViewCell keeps reloading as table is scrolled

I'm coming close to the end of development on a very substantial pet project that I've been putting off for years, and I've got an even more substantial problem that I've run into with an added bit of functionality.

Within this app, I have a UITableView that has a custom cell with a UIScrollView. Inside this scroll view, I dynamically populate it with the contents of an array. Though I got this working perfectly (ish), it came with an unexpected side effect: Whenever the table is scrolled, the UIScrollViews don't refresh as I'd expect them to, and generate more UILabels within themselves.

Here you can see the UITableViewCell with the UIScrollViews, and here you can see what happens after just one scroll through the table. It goes without saying, but more scrolling leads to a worsened effect, and eventually the memory use becomes unsustainable and the UX is... well, it just isn't anything I'd call an experience.

The offending code is below, and it's in the tableView:cellForRowAtIndexPath: method.

int stopCount = (int)[[busStop valueForKey:@"Stop Times"] count];
int horizontalSpacing = 0;
for (int i = 0; i < stopCount; i++) {
    UILabel *timeLabel;
    if (!timeLabel) {
        timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(horizontalSpacing, 0, 75, 20)];
        timeLabel.text = [[busStop valueForKey:@"Stop Times"] objectAtIndex:i];
        timeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:17.0];
        horizontalSpacing += timeLabel.bounds.size.width;
        [cell.stopTimesView addSubview:timeLabel];
    }
}
cell.stopTimesView.contentSize = CGSizeMake(horizontalSpacing, 20);

I'm suspecting that this is neither the time nor the place to be populating the scroll view, but I'm stuck as to where a more appropriate place to put it would be (perhaps the custom cell class methods?).

I greatly appreciate any and all assistance that anyone could provide on this matter.

Upvotes: 0

Views: 506

Answers (1)

Cihan Tek
Cihan Tek

Reputation: 5409

The output you got is not suprising because you keep adding new UILabels to the UIScrollView in each cell without deleting the old ones first. Clear the content of the UIScrollView before adding new labels into it by doing something like this

[cell.stopTimesView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]

Also, I don't see the point of the code below:

UILabel *timeLabel;
if (!timeLabel)

Since you have defined timeLabel in the line above, it clearly will have the value of nil, and hence the if statement is unnecessary.

So your final code should be like this:

int stopCount = (int)[[busStop valueForKey:@"Stop Times"] count];
int horizontalSpacing = 0;

[cell.stopTimesView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

for (int i = 0; i < stopCount; i++) {
    UILabel *timeLabel = timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(horizontalSpacing, 0, 75, 20)];
    timeLabel.text = [[busStop valueForKey:@"Stop Times"] objectAtIndex:i];
    timeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:17.0];
    horizontalSpacing += timeLabel.bounds.size.width;
    [cell.stopTimesView addSubview:timeLabel];
}
cell.stopTimesView.contentSize = CGSizeMake(horizontalSpacing, 20);

Upvotes: 2

Related Questions