Как реализовать UICollectionViewCells, показывающий содержимое с сохранением состояния?

В настоящее время я занимаюсь рефакторингом своего приложения Newsstand.

Ранее я показывал несколько пользовательских UIView («CoverView») в саморассчитываемой сетке (3 элемента в строке, столько строк, сколько необходимо), встроенной в представление прокрутки с вертикальной прокруткой.

Каждый «CoverView» состоит из

  • ярлык (показывающий название проблемы)
  • изображение (показывающее обложку выпуска)
  • кнопка (показывающая "СКАЧАТЬ" или - если уже загружена - "ЧИТАТЬ")
  • индикатор выполнения (изначально скрыт, показывает ход загрузки)

Каждый CoverView имеет свои собственные UITapGestureRecognizer и UILongPressGestureRecognizer.

Если пользователь нажимает один раз, кнопка скрывается, отображается индикатор выполнения загрузки, который постоянно обновляется в соответствии с ходом загрузки:

 [issue addObserver:cover forKeyPath:@"downloadProgress" options:NSKeyValueObservingOptionNew context:NULL]; 

(Распознаватель длительного нажатия позволяет пользователю удалить проблему).

Все CoverView хранятся в NSMutableDictionary и всегда хранятся в памяти. Хотя немасштабированные изображения довольно большие (высота 1024 пикселя), у меня никогда не было проблем с производительностью при прокрутке, вероятно, потому, что не так много проблем (и, следовательно, CoverViews) для хранения.

Поскольку самореализованная сетка-макет сложна и сложна в обслуживании, я хотел вместо этого использовать UICollectionView. Я добавил представление коллекции и сделал свой класс CoverView наследником UICollectionViewCell (вместо UIView).

Отображение и прокрутка работают, но у меня следующие проблемы:

  1. Прокрутка отстает, когда необходимо отобразить новую строку ячеек, и для каждой вызывается collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath.

  2. Я пытался не использовать повторно ячейки (как ни странно, для повышения производительности), но это не удалось из-за того, что для каждой ячейки должен быть установлен свой идентификатор повторного использования (а свойство "reuseIdentifier" доступно только для чтения, поэтому я не могу установить это в коде).

  3. Я не знаю, где отключить обозреватели КВО для ячейки. Есть ли способ получать уведомления, когда ячейка ставится в очередь для повторного использования?

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


person thomers    schedule 28.02.2013    source источник
comment
Я надеюсь, что этот код будет полезен для вас: github.com/lequysang/TestCollectionViewWithProgressBar   -  person LE SANG    schedule 28.02.2013
comment
Санг, спасибо - загрузка фактически обрабатывается в классе Issue (который действует как модель и не имеет элементов GUI или -зависимостей).   -  person thomers    schedule 28.02.2013


Ответы (1)


Чтобы установить «reuseIdentifier», правильный дизайн заключается в использовании методов UICollectionView:

  • registerClass:forCellWithReuseIdentifier:
  • or registerNib:forCellWithReuseIdentifier:

Обычно вы вызываете эти методы один раз, в зависимости от того, как вы хотите предоставить экземпляр вашей ячейки (раздутый из NIB или созданный с помощью стандартного [[ViewClass alloc] init]

После регистрации представлений вы можете использовать их из UiCollectionView следующим образом:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"yourReuseId" forIndexPath:indexPath];
    // Collection view handle ALL the work :
    // 1 - retrieves a reusable view if views have already been recycled
    // or 2- instantiate a new one, using the class/nib you registered
    // So, cell SHOULDN'T be nil from here :)


    // Note : from iOS 6, UITableView has a similar auto-instantiation mechanism

}

3 - чтобы отключить KVO, переопределить метод -(void)prepareForReuse UICollectionViewCell (унаследован от UICollectionReusableView)

person Vinzzz    schedule 28.02.2013