0

Я пытаюсь создать интерфейс, который может содержать «представления» разных размеров и т.д. Для этого я использую UICollectionView с этими клетками:UICollectionView Jumpy прокрутки

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
    Card *card = [[[usermanager getSelectedUser] getCards] objectAtIndex:indexPath.item]; 
    UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cardCell" forIndexPath:indexPath]; 
    [cell addSubview:card]; 

    [cell.layer setBorderColor:[UIColor redColor].CGColor]; 
    [cell.layer setBorderWidth:1.0f]; 
    [cell.layer setMasksToBounds:NO]; 
    return cell; 
} 

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

Очень важно отметить, что контент является динамическим. Пользователь должен иметь возможность добавлять и удалять карты во время выполнения.

Благодаря

+0

Как долго '[[usermanager getSelectedUser] getCards]' принимает выполнение? – trojanfoe

+0

У вас есть собственный макет? Если да, убедитесь, что вы подклассифицируете 'UICollectionViewLayout' и используете' UICollectionViewLayoutInvalidationContext' при аннулировании макета. – Dennis

+0

@Dennis Я использую CHTCollectionViewWaterFallLayout –

ответ

1

Я как-то понял. Некоторые из моих карт содержали изображения, и каждый раз, когда я прокручивал систему, она перезагружала бы все эти изображения из памяти. Это сделало прокрутку относительно медленной и изменчивой.

1

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

Кроме того, при повторном использовании такой ячейки вы должны проверить, добавила ли существующая ячейка Card. При повторном использовании afaik iOS автоматически не удаляет добавленные subviews (поэтому для повторно используемой ячейки addSubview может выполняться несколько раз с разными Картами, вы можете проверить это с помощью отладки представления).

Вы также можете лениво загрузить содержимое ячейки.

+0

Проблема: все содержимое динамическое. Пользователь может добавлять или удалять карты во время выполнения –

+0

@BlackMagic. Вы просто должны быть уверены, что правильно используете эти ячейки. Возможно, добавьте тег в подкатегорию Card и каждый раз перед добавлением новой Карты просто удалите старую (если она существует). '[[cell viewWithTag: CARDTAG] removeFromSuperview]' – Templar

+0

Я не уверен, что вы понимаете, что я пытаюсь сделать. Каждая ячейка содержит одну карту. И количество ячеек может варьироваться, а также размер ячеек индивидуально –

1

Как я могу понять из вашего кода, на каждом вызове cellForItemAtIndexPath вы создаете новый объект карты и добавляете его как подпункт в ячейке.

Вы фактически не используете возможность повторного использования ячейки. Попробуйте добавить элементы пользовательского интерфейса в ячейку (раскадровку или xib, что бы вы ни использовали). Затем задайте значения этих элементов на основе указательного пути. Это устранит задержку при прокрутке.

Импорт Также <QuartzCore/QuartzCore.h>

[cell.layer setShadowPath:[[UIBezierPath 
          bezierPathWithRect:self.bounds] CGPath]]; 

[cell.layer setBorderColor:[UIColor redColor].CGColor];  
[cell.layer setBorderWidth:1.0f]; 
[cell.layer setMasksToBounds:NO]; 
+0

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

2

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

Прежде всего, если вы нацеливаетесь на iOS 8 и выше, были сделаны огромные улучшения в UICollectionView, которые вы абсолютно должны обязательно использовать, если это возможно. Видео WWDC 2014 года What's New in Table and Collection Views дает вам хороший обзор. Ключевым моментом является то, что IOS 8 добавляет три новых методов UICollectionViewLayoutInvalidationContext:

- invalidateItemsAtIndexPaths: 
- invalidateSupplementaryElementsOfKind:atIndexPaths: 
- invalidateDecorationElementsOfKind:atIndexPaths: 

Используя эти методы вместе с UICollectionViewLayout invalidationContextForBoundsChange: вы можете сузить чрезвычайно количество элементов, макет должен обрабатывать. Это даст вам оптимальную производительность.

Если, как и мне, вам также необходимо установить цель iOS 7, все усложняется. Есть два важных методов в макете, что вы можете улучшить:

  • Во-первых, shouldInvalidateLayoutForBoundsChange: где расследуют измененные границы и убедитесь, что вы недействительным только в случае крайней необходимости полного макета.
  • Во-вторых, prepareLayout, который должен вызываться только в том случае, если полный макет недействителен.

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

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

Смежные вопросы