2013-06-04 3 views
42

У меня есть UICollectionViewController, который использует стандартный UICollectionViewFlowLayout для отображения одного вертикального столбца ячеек. Я пытаюсь создать анимацию expand/collapse на ячейке при прослушивании ячейки. Я использую следующий код для достижения этой цели:Изменение размера анимирующей ячейки UICollectionView вызывает нежелательное поведение

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath (NSIndexPath *)indexPath 
{ 
    [self.feedManager setCurrentlySelectedCellIndex:indexPath.item]; 
    [self.collectionView performBatchUpdates:nil completion:nil]; 
} 

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    //Return the size of each cell to draw 
    CGSize cellSize = (CGSize) { .width = 320, .height = [self.feedManager heightForCellAtIndexPath:indexPath] }; 
    return cellSize; 
} 

Свойство «selectedCellIndex» на мой управляющий объект указывает модель данных для возврата в развернутом или свернутом размер внутри в heightForCellAtIndexpath:

[self.collectionView performBatchUpdates:nil completion:nil]; 

Тогда performBatchUpdates:completiong: метод анимирует это изменение размера красиво. Однако! Когда происходит анимация, расширяющаяся ячейка может вызвать частично видимую ячейку в нижней части экрана, чтобы выйти из экрана.

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

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

+0

Я нашел очень похожую проблему, когда выворачивался вокруг http://stackoverflow.com/questions/13698275/uicollectionview-moveitematindexpathtoindexpath-issues-moving-items-not-on-scr –

+0

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

+0

У меня точно такая же проблема, и мне бы очень понравилось решение, даже если это решение - номер радара! – jrturton

ответ

27

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

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath 
{ 
    UICollectionViewLayoutAttributes *pose = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath]; 
    if (<test for incorrect frame>) { 
     CGRect frame = pose.frame; 
     frame.origin.y = <calculate correct frame>; 
     pose.frame = frame; 
    } 
    return pose; 
} 

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

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

Дайте мне знать, если вам нужна дополнительная помощь.

EDIT

Если вы заинтересованы в поиске на макете 3-й партии, я открытый исходный код моего пользовательского шаблона сетки VCollectionViewGridLayout и добавил пример проект демонстрирует плавный расширяющимся рост клеток. Попробуйте запустить Expand project. Существует также Sort & Filter project с анимированной сортировкой и фильтрацией. Оба проекта позволяют переключаться между раскладкой и сеткой, чтобы вы могли видеть улучшение.

+0

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

+1

О да, и есть 200 очков! – jrturton

+0

@TimothyMoose, как я должен включать VCollectionViewLayout и TLIndexPathTools внутри моего проекта xcode? Я просто добавил файлы VCollectionViewLayout.h, VCollectionViewLayout.m и перетащил файл проекта TLIndexPathTools в группу проектов Framework, добавив его как Dependency and Linked Framework в Build Phases, но я получаю следующую ошибку: Неопределенные символы для архитектуры i386: " _OBJC_CLASS _ $ _ NSManagedObject ", ссылка от: objc-class-ref в libTLIndexPathTools.a (TLIndexPathDataModel.o) – ftartaggia

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