0

In a wish to improve UITableView performance, I'm thinking of relocating all of my UITableViewCell's settings outside cellForRowAtIndexPath.

At this moment, I have several custom cells inside my tableview that I set inside cellForRowAtIndexPath. But because of this, everytime I scroll inside my tableview and so everytime a cell has to be shown on screen, the settings is done again, causing a lag.

I've tried to put settings inside viewDidLoad by using a class variable for my cell but with no effect. Do you have any idea where I could move all of my cells' settings but especially if it's possible ?

Thanks in advance and have a nice day !

EDIT : As asked, here is my cellForRowAtIndexPathMethod :

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

NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.delegate = self;


if ([appliedTheme hasPrefix:@"DarkMode"]) {

    self.tableView.backgroundColor = [UIColor colorWithRed:0.20 green:0.20 blue:0.20 alpha:1.0];
    cell.backgroundColor = [UIColor colorWithRed:0.20 green:0.20 blue:0.20 alpha:1.0];
    cell.cardView.backgroundColor = [UIColor colorWithRed:0.30 green:0.30 blue:0.30 alpha:1.0];


    cell.webServerIntroLabel.textColor = [UIColor whiteColor];
    cell.webServerOptionsTitle.textColor = [UIColor whiteColor];
    cell.webServerOptionsReachableAtLabel.textColor = [UIColor whiteColor];

}else {

    self.tableView.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.0];
    cell.backgroundColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:1.0];
    cell.cardView.backgroundColor = [UIColor whiteColor];


    cell.webServerIntroLabel.textColor = [UIColor blackColor];
    cell.webServerOptionsTitle.textColor = [UIColor blackColor];
    cell.webServerOptionsReachableAtLabel.textColor = [UIColor blackColor];

}


if ([CellIdentifier isEqualToString:@"webServerIntro"]) {

    cell.webServerIntroImageView.image = [UIImage imageNamed:webServerIntroIconToShow];
    cell.webServerIntroLabel.adjustsFontSizeToFitWidth = YES;
    cell.webServerIntroLabel.numberOfLines = 0;
    [cell.webServerIntroLabel sizeToFit];
    cell.webServerIntroLabel.text = @"Some text";

}else if ([CellIdentifier isEqualToString:@"webServerOptions"]) {        

    cell.webServerOptionsTitle.adjustsFontSizeToFitWidth = YES;
    cell.webServerOptionsTitle.text = NSLocalizedString(@"Web Server Options", nil);
    cell.webServerOptionsStatusLabel.adjustsFontSizeToFitWidth = YES;

    if (!webServerStarted) {

        cell.webServerOptionsImageView.image = [UIImage imageNamed:@"Not-Checked"];
        cell.webServerOptionsStatusLabel.text = NSLocalizedString(@"Not Running", nil);
        cell.serverURLLabel.text = NSLocalizedString(@"Not Reachable", nil);
        cell.ipAddressURLLabel.text = NSLocalizedString(@"Not Reachable", nil);
        [cell.startStopWebServerButton setTitle:NSLocalizedString(@"Start Web Server", nil) forState:UIControlStateNormal];


        cell.webServerStartedBool = NO;

    }else {

        NSString *serverURL = [self deviceName];
        serverURL = [serverURL stringByReplacingOccurrencesOfString:@" " withString:@"-"];


        cell.webServerOptionsImageView.image = [UIImage imageNamed:@"Checked"];
        cell.webServerOptionsStatusLabel.text = NSLocalizedString(@"Running", nil);
        cell.serverURLLabel.text = [NSString stringWithFormat:@"http://%@.local", serverURL];
        cell.ipAddressURLLabel.text = [NSString stringWithFormat:@"%@", webUploader.serverURL];
        [cell.startStopWebServerButton setTitle:NSLocalizedString(@"Stop Web Server", nil) forState:UIControlStateNormal];


        cell.webServerStartedBool = YES;

    }

    cell.webServerOptionsStatusLabel.textColor = [UIColor lightGrayColor];
    cell.webServerOptionsReachableAtLabel.adjustsFontSizeToFitWidth = YES;
    cell.webServerOptionsReachableAtLabel.text = NSLocalizedString(@"Reachable At :", nil);
    cell.ipAddressURLLabel.adjustsFontSizeToFitWidth = YES;
    cell.ipAddressURLLabel.textColor = [UIColor lightGrayColor];
    cell.ipAddressURLLabel.layer.borderWidth = 1.0f;
    cell.ipAddressURLLabel.layer.borderColor = [[UIColor lightGrayColor] CGColor];
    cell.ipAddressURLLabel.layer.cornerRadius = 5;
    cell.serverURLLabel.adjustsFontSizeToFitWidth = YES;
    cell.serverURLLabel.textColor = [UIColor lightGrayColor];
    cell.serverURLLabel.layer.borderWidth = 1.0f;
    cell.serverURLLabel.layer.borderColor = [[UIColor lightGrayColor] CGColor];
    cell.serverURLLabel.layer.cornerRadius = 5;
    cell.startStopWebServerButton.layer.borderWidth = 1.0f;
    cell.startStopWebServerButton.layer.borderColor = [[UIColor clearColor] CGColor];
    cell.startStopWebServerButton.layer.cornerRadius = 5;
    cell.startStopWebServerButton.titleLabel.adjustsFontSizeToFitWidth = YES;


    if ([appliedTheme isEqualToString:@"Default-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0 green:0.478 blue:0.875 alpha:1]; /*#007ADF : Bleu iOS*/

    }else if ([appliedTheme isEqualToString:@"Red-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.90 green:0.07 blue:0.00 alpha:1.0]; /*#E61100 : Rouge*/

    }else if ([appliedTheme isEqualToString:@"Orange-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.83 green:0.33 blue:0.00 alpha:1.0]; /*#D35400 : Orange*/

    }else if ([appliedTheme isEqualToString:@"Yellow-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.95 green:0.61 blue:0.07 alpha:1.0]; /*#F39C12 : Jaune*/

    }else if ([appliedTheme isEqualToString:@"Green-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.15 green:0.68 blue:0.38 alpha:1.0]; /*#27AE60 : Vert*/

    }else if ([appliedTheme isEqualToString:@"Purple-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.56 green:0.27 blue:0.68 alpha:1.0]; /*#8E44AD : Violet*/

    }else if ([appliedTheme isEqualToString:@"Gray-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.74 green:0.76 blue:0.78 alpha:1.0]; /*#BDC3C7 : Gris*/

    }else if ([appliedTheme isEqualToString:@"DarkGray-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.50 green:0.55 blue:0.55 alpha:1.0]; /*#7F8C8D : Gris foncé*/

    }else if ([appliedTheme isEqualToString:@"DesaturatedBlue-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.17 green:0.24 blue:0.31 alpha:1.0]; /*#2C3E50 : Bleu désaturé*/

    }else if ([appliedTheme isEqualToString:@"VeryDarkGray-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.20 green:0.20 blue:0.20 alpha:1.0]; /*#333333 : Gris très foncé*/

    }else if ([appliedTheme isEqualToString:@"Black-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.00 green:0.00 blue:0.00 alpha:1.0]; /*#000000 : Noir*/

    }else if ([appliedTheme isEqualToString:@"DarkModeDefault-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0 green:0.478 blue:0.875 alpha:1]; /*#007ADF : Bleu iOS*/

    }else if ([appliedTheme isEqualToString:@"DarkModeRed-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.90 green:0.07 blue:0.00 alpha:1.0]; /*#E61100 : Rouge*/

    }else if ([appliedTheme isEqualToString:@"DarkModeOrange-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.83 green:0.33 blue:0.00 alpha:1.0]; /*#D35400 : Orange*/

    }else if ([appliedTheme isEqualToString:@"DarkModeYellow-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.95 green:0.61 blue:0.07 alpha:1.0]; /*#F39C12 : Jaune*/

    }else if ([appliedTheme isEqualToString:@"DarkModeGreen-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.15 green:0.68 blue:0.38 alpha:1.0]; /*#27AE60 : Vert*/

    }else if ([appliedTheme isEqualToString:@"DarkModePurple-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.56 green:0.27 blue:0.68 alpha:1.0]; /*#8E44AD : Violet*/

    }else if ([appliedTheme isEqualToString:@"DarkModeGray-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.74 green:0.76 blue:0.78 alpha:1.0]; /*#BDC3C7 : Gris*/

    }else if ([appliedTheme isEqualToString:@"DarkModeDarkGray-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.50 green:0.55 blue:0.55 alpha:1.0]; /*#7F8C8D : Gris foncé*/

    }else if ([appliedTheme isEqualToString:@"DarkModeDesaturatedBlue-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.17 green:0.24 blue:0.31 alpha:1.0]; /*#2C3E50 : Bleu désaturé*/

    }else if ([appliedTheme isEqualToString:@"DarkModeVeryDarkGray-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.20 green:0.20 blue:0.20 alpha:1.0]; /*#333333 : Gris très foncé*/

    }else if ([appliedTheme isEqualToString:@"DarkModeBlack-Theme"]) {

        cell.startStopWebServerButton.backgroundColor = [UIColor colorWithRed:0.00 green:0.00 blue:0.00 alpha:1.0]; /*#000000 : Noir*/

    }

}else {



}


return cell;

}

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Synny
  • 542
  • 1
  • 4
  • 18
  • Show your code. `cellForRowAt` should be a relatively small, quick function as it is called many times. You should not fetch data or perform complex calculations in this method. – Paulw11 Jun 21 '17 at 21:03
  • You can find the code in edit now ! – Synny Jun 21 '17 at 21:07

2 Answers2

2

While you have a lot of code there, nothing seems like it would be dreadfully slow.

It is a minor point in term of performance, but the code that sets the tableview's background colour should be in viewWillAppear rather than cellForRowAt as there is no need to set the background colour each time a cell is dequeued.

You can also simplify this function considerably by moving all of the theme-related code into the cell subclass. Call a function on the cell passing the theme and have the cell set all of that stuff; The same amount of code will be executed, but cellForRowAt will be smaller and easier to read.

Where I think you can get some performance is by eliminating the repeated string operations related to the theme. Create a class or struct that represents your theme and use an enumeration (This stuff is much easier is Swift, but you can still do it in ObjectiveC).

If you do this, then, for example,

if ([appliedTheme hasPrefix:@"DarkMode"])

becomes

if (appliedTheme.darkMode)

A complex string comparison is replaced with a simple boolean check; this is much faster

Similarly, using an enumeration for the theme you get something like

switch (appliedTheme.theme) {
    case DarkModeGreen-Theme:
       ...

Now an expesnsive string comparison has been replaced with a quick integer comparison.

Finally, creating UIColors is relatively expensive. You can move that into your Theme object too. When you create an instance of a Theme, expose the colours as properties. This way you get rid of the switch statement I suggested and creating the colours each time and simply say something like

cell.startStopWebServerButton.backgroundColor = appliedTheme.buttonBackgroundColor
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • Thanks for all your tips, I will implement these and see if I get improvement ! Anyway I appreciate the time you took for posting such good reply :) – Synny Jun 21 '17 at 21:25
0

Have to tried prepareforreuse. Apart from loading images I don't see other code that could cause the delay. Few things that might help

  1. Even though imagenamed should return a cache image if it's already loaded, try loading images async with GCD
  2. Is the web service code causing any delay?
  3. Run instruments (time profiler?) to see what is causing the lag or delay
Raj
  • 326
  • 1
  • 7
  • Sorry to have not added code at the beginning , you can find it in edit now ! – Synny Jun 21 '17 at 21:06
  • No that's not anything related to web server that's causing the lag as the issue is present even if it's not running ! To be more general the lag is also present on other classes that implement the custom cell class as well. So I think the issue is with image loading like you suggested and with theme management as Paulw11 suggested ! I will try what you've said also, thanks for your tips ;) – Synny Jun 21 '17 at 21:55