Nicola
Nicola

Reputation: 81

UITableview slow scroll and increase ram after some scrolls

this is my code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"hourCell" forIndexPath:indexPath];

// Configure the cell...


    cell.textLabel.text=hoursarray[indexPath.row];

    if ([cell.contentView subviews]){
        for (UIView *subview in [cell.contentView subviews]) {
            [subview removeFromSuperview];
        }
    }

    UIButton *buttonOff = [UIButton buttonWithType:UIButtonTypeCustom];

    buttonOff.layer.cornerRadius = 5.0f;
    UIButton *buttonT1 = [UIButton buttonWithType:UIButtonTypeCustom];
    buttonT1.layer.cornerRadius = 5.0f;
    UIButton *buttonT2 = [UIButton buttonWithType:UIButtonTypeCustom];
    buttonT2.layer.cornerRadius = 5.0f;      
    buttonOff.frame = CGRectMake(130, 5, 40, 34);
    [buttonOff setTitle:@"OFF" forState:UIControlStateNormal];
    [buttonOff addTarget:self action:@selector(onButtonOFFTap:) forControlEvents:UIControlEventTouchUpInside];
    buttonT1.frame = CGRectMake(190, 5, 40, 34);
    [buttonT1 setTitle:@"T1" forState:UIControlStateNormal];
    [buttonT1 addTarget:self action:@selector(onButtonT1Tap:) forControlEvents:UIControlEventTouchUpInside];
    buttonT2.frame = CGRectMake(250, 5, 40, 34);
    [buttonT2 setTitle:@"T2" forState:UIControlStateNormal];
    [buttonT2 addTarget:self action:@selector(onButtonT2Tap:) forControlEvents:UIControlEventTouchUpInside];

    [cell addSubview:buttonOff];
    [cell.contentView bringSubviewToFront:buttonOff];
    buttonOff.tag=indexPath.row;

    [cell addSubview:buttonT1];
    [cell.contentView bringSubviewToFront:buttonT1];
    buttonT1.tag=indexPath.row;

    [cell.contentView bringSubviewToFront:buttonT2];
    [cell addSubview:buttonT2];
    buttonT2.tag=indexPath.row;

    if([[NSString stringWithFormat:@"%@",[datiProgrTemp objectAtIndex:indexPath.row+48*day]] isEqual:@"1"])
    {
        buttonOff.backgroundColor = [UIColor greenColor];
        buttonT1.backgroundColor = [UIColor lightGrayColor];
        buttonT2.backgroundColor = [UIColor lightGrayColor];
    }
    if([[NSString stringWithFormat:@"%@",[datiProgrTemp objectAtIndex:indexPath.row+48*day]] isEqual:@"2"])
    {
        buttonOff.backgroundColor = [UIColor lightGrayColor];
        buttonT1.backgroundColor = [UIColor greenColor];
        buttonT2.backgroundColor = [UIColor lightGrayColor];
    }
    if([[NSString stringWithFormat:@"%@",[datiProgrTemp objectAtIndex:indexPath.row+48*day]] isEqual:@"3"])
    {
        buttonOff.backgroundColor = [UIColor lightGrayColor];
        buttonT1.backgroundColor = [UIColor lightGrayColor];
        buttonT2.backgroundColor = [UIColor greenColor];
    }
return cell;

}

The fact is that after two or three scrolls (fast and smooth) the scrolling goes slow and crappy and the ram used increase. I tried to put if(cell==nill) but I'm using storyboard and the cell is never nill

Am I wrong in something?

Thanks a lot, N.

Upvotes: 0

Views: 346

Answers (2)

Nicola
Nicola

Reputation: 81

Thanks to all. This is the code working good. I added a TableViewCell class that contains only the outlet to the buttons (added buttons graphically in the storyboard):

    #import <UIKit/UIKit.h>

@interface CHRTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIButton *buttonOFF;
@property (weak, nonatomic) IBOutlet UIButton *buttonT1;
@property (weak, nonatomic) IBOutlet UIButton *buttonT2;

@end

then instantiated cell on tableview controller and pointing to the outlet changed the button's aspect:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CHRTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"hourCell" forIndexPath:indexPath];

// Configure the cell...


    cell.textLabel.text=hoursarray[indexPath.row];


    cell.buttonOFF.layer.borderColor = [UIColor lightGrayColor].CGColor;
    cell.buttonOFF.layer.borderWidth = 0.5f;
    cell.buttonOFF.layer.cornerRadius = 5.0f;

    cell.buttonT1.layer.borderColor = [UIColor lightGrayColor].CGColor;
    cell.buttonT1.layer.borderWidth = 0.5f;
    cell.buttonT1.layer.cornerRadius = 5.0f;

    cell.buttonT2.layer.borderColor = [UIColor lightGrayColor].CGColor;
    cell.buttonT2.layer.borderWidth = 0.5f;
    cell.buttonT2.layer.cornerRadius = 5.0f;

    [cell.buttonOFF setTitle:@"OFF" forState:UIControlStateNormal];
    [cell.buttonOFF addTarget:self action:@selector(onButtonOFFTap:) forControlEvents:UIControlEventTouchUpInside];
    [cell.buttonT1 setTitle:@"T1" forState:UIControlStateNormal];
    [cell.buttonT1 addTarget:self action:@selector(onButtonT1Tap:) forControlEvents:UIControlEventTouchUpInside];
    [cell.buttonT2 setTitle:@"T2" forState:UIControlStateNormal];
    [cell.buttonT2 addTarget:self action:@selector(onButtonT2Tap:) forControlEvents:UIControlEventTouchUpInside];

    cell.buttonOFF.tag=indexPath.row;
    cell.buttonT1.tag=indexPath.row;
    cell.buttonT2.tag=indexPath.row;


    if([[NSString stringWithFormat:@"%@",[datiProgrTemp objectAtIndex:indexPath.row+48*day]] isEqual:@"1"])
    {

        cell.buttonOFF.backgroundColor = [UIColor colorWithRed:0.0f/255.0f green:200.0f/255.0f blue:60.0f/255.0f alpha:1.0f];
        cell.buttonT1.backgroundColor = [UIColor whiteColor];
        cell.buttonT2.backgroundColor = [UIColor whiteColor];

    }
    if([[NSString stringWithFormat:@"%@",[datiProgrTemp objectAtIndex:indexPath.row+48*day]] isEqual:@"2"])
    {
        cell.buttonOFF.backgroundColor = [UIColor whiteColor];
        cell.buttonT1.backgroundColor = [UIColor colorWithRed:0.0f/255.0f green:200.0f/255.0f blue:60.0f/255.0f alpha:1.0f];;
        cell.buttonT2.backgroundColor = [UIColor whiteColor];
    }
    if([[NSString stringWithFormat:@"%@",[datiProgrTemp objectAtIndex:indexPath.row+48*day]] isEqual:@"3"])
    {
        cell.buttonOFF.backgroundColor = [UIColor whiteColor];
        cell.buttonT1.backgroundColor = [UIColor whiteColor];
        cell.buttonT2.backgroundColor = [UIColor colorWithRed:0.0f/255.0f green:200.0f/255.0f blue:60.0f/255.0f alpha:1.0f];;
    }

return cell;

}

Upvotes: 0

Lyndsey Scott
Lyndsey Scott

Reputation: 37290

There are a couple problems here.

The whole point of using dequeueReusableCellWithIdentifier: is to reuse your cells and their content. But I see you've used this line:

if ([cell.contentView subviews]){
    for (UIView *subview in [cell.contentView subviews]) {
        [subview removeFromSuperview];
    }
}

to remove the cell content at every call to cellForRowAtIndexPath:. This is a waste of using dequeueReusableCellWithIdentifier:.

Nevertheless, your logic is almost correct. You can remove the subviews and create new subviews without having the incremental memory issues you're describing. The problem is you've made a small error:

You're adding the UIButtons directly to the cell's view, for example

[cell addSubview:buttonOff];

but removing the subviews of the cell's content view:

[cell.contentView subviews]

(You're also using bringSubviewToFront: ineffectively for this same reason.)

Because of this mistake, you're not actually removing the buttons at every call to cellForRowAtIndexPath: as you've intended so as you scroll back and forth, buttons are being added one on top of another on top of another, thus increasing memory usage.

To fix this problem, whether you add and remove from cell or cell.contentView, you have to be consistent.

All that aside though, since the content of your cells is very similar, I highly recommend you use dequeueReusableCellWithIdentifier: in the way it was intended by actually reusing your cells' content.

Upvotes: 1

Related Questions