UITableView Lagging из-за теней и границ - PullRequest
5 голосов
/ 01 декабря 2011

У меня есть следующий код, чтобы добавить цвет границы и тень на фон моего UITableViewCell. Моя проблема заключается в том, что этот код вызывает огромное отставание самого tableView.

Подскажите, пожалуйста, как я могу оптимизировать свой код, предотвращая зависание UITableView?

if ([cell viewWithTag:012] == nil && comment.isReply == NO) {
    UIImageView *iv = [[[UIImageView alloc] initWithFrame:frame] autorelease];
    [iv setImage:[UIImage imageNamed:@"paper"]];
    [iv setTag:012];
    [cell insertSubview:iv atIndex:0];

    [iv.layer setBorderWidth:1.0];
    [iv.layer setBorderColor:[[UIColor whiteColor] CGColor]];

    [iv.layer setShadowColor:[[UIColor blackColor] CGColor]];
    [iv.layer setShadowOffset:CGSizeMake(0, 1)];
    [iv.layer setShadowOpacity:0.75];

}

else if ([cell viewWithTag:012] == nil && comment.isReply == YES) {

    frame.origin.x += 35;

    UIImageView *iv = [[[UIImageView alloc] initWithFrame:frame] autorelease];
    [iv setImage:[UIImage imageNamed:@"paper"]];
    [iv setTag:012];
    [cell insertSubview:iv atIndex:0];

    UIImage *arrow = [UIImage imageNamed:@"arrow"];
    UIImageView *ivs = [[[UIImageView alloc] initWithFrame:CGRectMake(-12, ([cell frame].size.width / 2) + ([arrow size].width/2) , arrow.size.width, arrow.size.height)] autorelease];
    [cell addSubview:ivs];

    [iv.layer setBorderWidth:1.0];
    [iv.layer setBorderColor:[[UIColor whiteColor] CGColor]];

    [iv.layer setShadowColor:[[UIColor blackColor] CGColor]];
    [iv.layer setShadowOffset:CGSizeMake(0, 0)];
    [iv.layer setShadowOpacity:0.75];

}

Ответы [ 2 ]

20 голосов
/ 01 декабря 2011

В дополнение к другим советам по оптимизации, указанным shadowPath на вашем CALayer будет улучшена производительность рисования теней.Вы можете определить путь для тени с помощью чего-то вроде этого ...

iv.layer.shadowPath = [UIBezierPath bezierPathWithRect:iv.bounds].CGPath;

Вы также можете захотеть взглянуть на бит shouldRasterize на CALayer.Это приводит к тому, что слой предварительно визуализируется как растровое изображение.Если вы идете по этому пути, обязательно предоставьте также растровую шкалу, соответствующую вашему устройству.

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
1 голос
/ 01 декабря 2011

Вы должны избегать манипулирования ячейкой при каждой загрузке, вместо этого вы должны настроить пользовательский интерфейс при инициализации / создании ячейки.

Чтобы проиллюстрировать это, каждый раз, когда вы прокручиваете новую ячейку (или несколько), можно загрузить с помощью метода cellForRowAtIndexPath:, в настоящее время вы делаете много изменений вида в этом методе, но могут быть случаи, когда это не нужно (например, новая ячейка того же типа, что и ячейка, которую только что прокрутили за пределы экрана). Переместите эту модификацию пользовательского интерфейса туда, где инициализируется ячейка, а не туда, где меняются данные. Вы можете сделать это с помощью подкласса или просто так.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Reuse id
    static NSString *identifier1 = @"identifer-1";
    static NSString *identifier2 = @"identifier-2";
    static NSString *regular = @"regular";

    UITableViewCell *cell;

    if (comment.isReply == NO) {
        cell = [tableView dequeueReusableCellWithIdentifier: identifier1];

        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: identifier1] autorelease];

            // Do the UI modification here
        }
    } else if (comment.isReply == YES) {
        cell = [tableView dequeueReusableCellWithIdentifier: identifier2];

        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: identifier2] autorelease];

            // Do the UI modification here
        }
    } else {
        // Regular cell
        cell = [tableView dequeueReusableCellWithIdentifier: regular];

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

    // Load the data into the cell

    return cell;
}

Надеюсь, вы поймете, что я делаю с этим, ключ в том, чтобы делать тяжелые вещи как можно меньше и позволить кешированию UITableView иметь больший эффект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...