Как повторно использовать / перерабатывать пользовательский элемент, как это делает uitableviewcell? - PullRequest
21 голосов
/ 06 февраля 2011

При использовании UITableView мы можем повторно использовать его ячейки, используя методы [[ UITableViewCell alloc] initWithStyle: reuseIdentifier:] и [uiTableViewInstance dequeueReusableCellWithIdentifier:].Это помогает контролировать память для огромных таблиц, поскольку в данный момент в представлении присутствует только несколько ячеек.

Я хочу создать UIScrollView, который имеет много подпредставлений.Вставка всех подпредставлений занимает много памяти и начального времени, которого я хочу избежать.Предоставляет ли Apple API способы повторного использования таких пользовательских компонентов (UIView или его подкласс здесь) так же, как представления ячеек с использованием идентификатора?

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

Вот пример кода, который я написал до сих пор:

int numberOfPages = 0;
int pageWidth = 100;
int pageHeight = 100

UIScrollView *myScrollView = //allocate and initialize a scrollview
//set its size to 100 by 100 (width equal to pageWidth)
//set paging enabled for myScrollView

Добавлениеподпредставления к нему из метода, который вызывается несколько раз

- (void) appendSubViewToScrollView {
    UIView *view = //allocate and initialize a view and dump data in it.

    CGRect rect = view.frame;
    rect.size.height = pageHeight;
    rect.size.width = pageWidth;
    rect.origin = CGPointMake(pageHeight * numberOfPages, 0);
    view.frame = rect;

    [myScrollView addSubview:view];

    numberOfPages++;

    [scrollView setContentSize:CGSizeMake(pageHeight * numberOfPages, pageWidth)];

    [view release];
}

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

1 Ответ

19 голосов
/ 06 февраля 2011

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

Таким образом, стандартный подход к утилизации требует использования нескольких ячеек.что равно количеству одновременно видимых видов на экране + количество дополнительных ячеек, которые вы можете получить при запуске прокрутки.Допустим, например, что вы показываете 5 полных представлений за раз (стабильная прокрутка), а затем при прокрутке вам понадобится один дополнительный вид, который частично показан, поэтому в конце вам нужно 5 + 1 = 6 представлений.Это в теории, рекомендуется использовать еще 2 просмотра.Таким образом, вам нужно написать два пула: один называется «visibleViews», который состоит из всех представлений, добавленных как подпредставления к представлению прокрутки, а другой называется «availableViews», который состоит из всех представлений, доступных для повторного использования.Затем вы создаете все эти виды и добавляете их в представление с прокруткой (да: вам нужно настроить их рамку в соответствии с их положением в представлении прокрутки, и да, вам необходимо заново настроить содержимое).Наконец, вам нужно отследить движение вида прокрутки, установив делегата.Цель этого отслеживания состоит в том, чтобы вычислить, какое из видимых представлений больше не является видимым, затем удалить его из видимого пула и перейти к используемому пулу.Кроме того, делегат должен понимать, когда должна появиться новая ячейка, но она все еще не видна, затем получить ее из доступного пула (или выделить / инициализировать, если пул пуст) и добавить в видимый пул и в качестве подпредставленияскроллвьюКонечно, если вы хотите повысить производительность, вы можете поместить больше подпредставлений в представление прокрутки, чтобы избежать точного перемещения ячеек, когда они начинают появляться на экране, поэтому я рекомендовал использовать несколько дополнительных представлений по бокам от представления прокрутки..

На WWDC 2010 есть отличное видео (вы можете получить к нему доступ, если вы являетесь зарегистрированным разработчиком) об использовании представлений прокрутки в iOS: оно объясняет эту технику.

PhotoScroller от AppleПример кода в документации XCode, по сути, делает то, что указано в видео WWDC, и объясняет эту технику.

...