Проблема обновления UITableViewCells при вращении UITableView - PullRequest
5 голосов
/ 08 сентября 2010

У меня есть UILabel в пользовательском UITableViewCell, размер которого изменяется при повороте устройства. Текст в этой метке необходимо пересчитать после поворота, потому что я сокращаю его до нужного размера и добавляю немного текста в конце.

например. у модели данных есть: «Это предварительное предложение, которое нужно остановить.»

В портретном режиме он становится "Это отправка отправлена ​​... подробнее"

В альбомном режиме это становится "Это предложение, которое ... больше"

С (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation Я могу получить доступ к видимым UITableViewCells и обновить описания.

Кажется, проблема в том, что существуют UITableViewCell, которые кэшируются, но я не могу добраться до них. Когда я прокручиваю UITableView после поворота, одна или две ячейки, которые находятся ниже видимой области после поворота, не имеют правильного текста в метке. Таким образом, они не были обработаны с помощью (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath - но они не были возвращены [tableView visibleCells] (или с помощью циклического просмотра всех представлений, возвращаемых с помощью [tableView subViews]).

Я пытался получить доступ к «дополнительным» ячейкам с помощью этого метода:

for (int index=max + 1; index < max + 3 && index < [cellTypes count]; index++) {
    NSIndexPath *updatedPath = [NSIndexPath indexPathForRow:index inSection:0];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:updatedPath];
    if (cell == nil) { continue; }
    [self updateCellForRotate:cell forRow:index];
}

(где max - самая большая строка, возвращаемая из visibleCells), но ячейка всегда равна nil.

Есть ли способ очистить кэш UITableViewCells, чтобы они не использовались повторно? Или получить к ним доступ, чтобы я мог их обновить?

Спасибо!

Ответы [ 5 ]

15 голосов
/ 12 ноября 2011

Две вещи. Первый. В вашем методе didRotateFromInterfaceOrientation вы можете просто перезагрузить видимые строки следующим образом:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation) fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    NSLog(@"didRotateFromInterfaceOrientation:%d",fromInterfaceOrientation);
    [tableView reloadRowsAtIndexPaths:[tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
}

Тогда я бы порекомендовал добавить либо число interfaceOrientation, либо просто ширину таблицы к имени ячейки очереди, чтобы tableView знал, что ячейки в одном повороте отличаются от ячеек в другом. Вот так:

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath withType:(NSString *)s_type
{
    UITableViewCell *cell = nil;
    // add width of table to the name so that rotations will change the cell dequeue names
    s_cell = [s_cell stringByAppendingString:[NSString stringWithFormat:@"%@%d",@"Width",(int)tv.bounds.size.width]];

    NSLog(@"%@",s_cell);
    cell = [tv dequeueReusableCellWithIdentifier:s_cell];
    if( cell == nil ) { 
        cell = [[[UITableViewCell alloc];
        initWithFrame:CGRectZero reuseIdentifier:s_cell] autorelease];
    }
}
1 голос
/ 08 сентября 2010

Во-первых, для перезагрузки всех ячеек таблицы используйте [self.tableView reloadData]

Во-вторых, добавьте строку кода, которая отвечает за сжатие, внутри метода (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.

Пример:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    //Some identifier and recycling stuff

    if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
        //Make labels smaller
    }
    else {
        //Make them bigger
    }
}

Или вы можете просто вызвать свой метод updateCellForRotate:forRow: при их создании. Но я не уверен, как эта функция работает, поэтому я не могу быть слишком конкретным.

0 голосов
/ 15 октября 2012

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

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

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

Я пробовал все применимые ответы выше, пока не посмотрел поближе на код cellForRowAtIndexPath:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

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

РЕДАКТИРОВАТЬ: В моемВ собственном приложении у меня будет максимум 20-30 строк, так как лично мне не нравятся очень длинные таблицы.Если бы для определенного запроса было возвращено много строк, у меня было бы несколько доступных фильтров, чтобы помочь им разобраться, какие строки им нужны.Если вы собираетесь отображать множество строк, то снятие их с очереди может вызвать нежелательное влияние на производительность.

Все, что я сделал, это закомментировал if и theследующая скобка, и ячейки моего стола обновились точно так, как я этого хотел:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
//}

Извинения за вафлю и поздний ответ на старый вопрос.

Бен.

Вафли и сливки или сироп.

0 голосов
/ 03 августа 2012

Вы можете использовать эту простую строку в методе shouldAutorotateToInterfaceOrientation :

self.view.autoresizesSubviews = YES;

Для меня это работает всегда успешно

0 голосов
/ 08 сентября 2010

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

Надеюсь, это поможет,
jrtc27

EDIT:

Вы говорите, что это пользовательские ячейки - не могли бы вы обновить свой текст в вашем UITableViewCell подклассе?

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