Анимация большого количества строк/секций в низкой производительности UITableView

мы не говорим о тысячах строк или чего-то еще, хотя, если бы был способ сделать вещи такими высокими, мне бы это понравилось.

У меня есть таблица с 27 разделами и 180 строк, распределенных по всем разделам, и сценарий, который я сейчас застрял, - это когда я одушевляю вещи в состояние модели только с тремя разделами и 5 строками и (что еще хуже) назад.

Я загружаю все анимации с помощью beginUpdates/endUpdates. Мое приложение довольно хорошо блокируется в течение 1-2 секунд на iphone4, пока оно выделяется, а затем запускаются анимации.

Я пробовал как анимировать удаление/добавление каждой строки, сохраняя разделы (и отбрасывая количество строк до 0 в случае удаления), а также анимируя только удаление/вставку самих разделов (когда количество строк упало бы до 0). Я бы предположил, что последний даст лучшую производительность, но это совсем не изменило ситуацию.

Есть ли что-нибудь, что можно сделать в конце приложения, чтобы ускорить это? Прямо сейчас у меня есть довольно грубый бит кода для спасения отдельных анимаций, если их более 20, вместо этого вместо этого нужно просто перезагрузить Data.

изменить здесь код, который обнаруживает проблему. Производительность этого кода немного лучше, чем эквивалентный код monotouch (это то, что я использовал раньше), но это все еще довольно плохо.

#import "TableViewController.h"

@interface MyTableViewDataSource : NSObject<UITableViewDataSource> {
    int rows;
};

@end

@implementation MyTableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (void)setRowCount:(int)r
{
    rows = r;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return rows;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell)
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    cell.textLabel.text = [NSString stringWithFormat:@"row %d", indexPath.row];

    return cell;
}

@end

@implementation MyTableViewController {
    UIBarButtonItem *populateButtonItem;
};

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        populateButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Populate" style:UIBarButtonItemStylePlain target:self action:@selector(populateDataSource)];
    }
    return self;
}

- (void)populateDataSource
{
    NSMutableArray* new_rows = [[NSMutableArray alloc] init];
    [((MyTableViewDataSource*)self.tableView.dataSource) setRowCount:200];

    for (int i = 0; i < 200; i ++)
        [new_rows addObject:[NSIndexPath indexPathForRow:i inSection:0]];

    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:new_rows withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.tableView.dataSource = [[MyTableViewDataSource alloc] init];
    self.navigationItem.rightBarButtonItem = populateButtonItem;
}

@end

Ответ 1

Имеет смысл только оживить видимые строки. Вместо того, чтобы делать анимацию для всех строк, которые вы вставляете, рассмотрите возможность анимирования вставки тех строк, которые будут видны.

Кроме того, вы уверены, что это анимация, вызывающая задержку? Получается ли такая же задержка, если вы передаете UITableViewRowAnimationNone для анимации, или это быстрее? Если это быстрее, то опять же, избегайте анимации тех вставок, которые не будут видны. (Вы можете выяснить, какие строки в настоящее время видны с помощью -indexPathsForVisibleRows.) Если это не так, то проблема, вероятно, вообще не связана с анимацией, а скорее накладные расходы на вставку нескольких сотен строк одновременно. Перезагрузка всей таблицы, как вы сейчас делаете, - это один из вариантов; вставка строк в меньшие партии - это другое.

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

Ответ 2

Вы используете UITableViewRowAnimationAutomatic (Ссылка: представление таблицы выбирает для вас соответствующий стиль анимации. (Представлено в iOS 5.0.)), и по какой-то причине представление в таблице выбирает очень плохое, которое исчезает в все строки при их расширении. Изменение непрозрачности на 200 UIViews при изменении размера кадра и перемещении их вокруг HAS должно быть медленным.:)

Вы можете просто сделать это:

[self.tableView insertRowsAtIndexPaths:new_rows withRowAnimation:UITableViewRowAnimationNone];

Это уменьшит анимацию до очень простой анимации UITableView при вставке строк, что, на мой взгляд, является абсолютно достаточным при вставке этого числа.

Ответ 3

Вы можете попробовать настроить пользовательский UITableViewCell и пользовательский чертеж, проверить этот проект, раздел te, который рассказывает о TableView и быстрой ячейке.

http://iosboilerplate.com/#uitableview

Ответ 4

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

Для разных видов анимации уже созданы некоторые пользовательские элементы управления, в которых вы можете иметь более быструю анимацию с реалистичной реализацией одного liner: Здесь есть взгляд.