Вращение интерфейса UICollectionView с пользовательским макетом

Я вижу какое-то загадочное поведение UICollectionView с пользовательским макетом (подкласс UICollectionViewLayout) при повороте устройства.

У меня есть простой горизонтально прокручиваемый ряд ячеек. При повороте устройства из портретной в альбомную ориентацию становятся видны дополнительные ячейки, которых раньше не было видно, а анимация этих появляющихся ячеек неправильная (используется знакомый эффект ореола, который, как я думаю, является своего рода эффектом анимации по умолчанию для просмотра коллекции). макеты). Обратите внимание на ячейку, появляющуюся в крайнем левом углу этой анимации:

UICollectionViewRotationGhosting

Некоторые подробности о настройке пользовательского макета:

  • shouldInvalidateLayoutForBoundsChange: возвращает YES.
  • In layoutAttributesForItemAtIndexPath: кэширует атрибуты в словаре, если они еще не созданы.
  • В layoutAttributesForElementsInRect: я рассчитываю вручную, какие ячейки должны быть видны, и каждый раз немного подстраиваю их свойство centre, прежде чем возвращать их атрибуты.

Затем у меня есть следующий код для работы с начальными/конечными атрибутами макета:

- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds
{
    [super prepareForAnimatedBoundsChange:oldBounds];
    self.animatingBoundsChange = YES;
}

- (void)finalizeAnimatedBoundsChange
{
    [super finalizeAnimatedBoundsChange];
    self.animatingBoundsChange = NO;
}

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    if (self.animatingBoundsChange) {
        // If the view is rotating, appearing items should animate from their current attributes (specify `nil`).
        // Both of these appear to do much the same thing:
        //return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
        return nil;
    }
    return [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
}

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    if (self.animatingBoundsChange) {
        // If the view is rotating, disappearing items should animate to their new attributes.
        return [self layoutAttributesForItemAtIndexPath:itemIndexPath];
    }
    return [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];
}

Мне кажется, что начальные атрибуты макета для вновь появляющейся ячейки какие-то неправильные (в конце концов, она заканчивается в правильном месте). Но когда я регистрирую свойство center атрибутов макета, возвращенных из метода initalLayout..., все выглядит правильно — все равномерно распределено по горизонтальной оси.

Единственная отличительная особенность ячейки, которая не анимируется правильно, заключается в том, что ее ячейка не возвращается в массиве [collectionView visibleCells] при вызове метода initialLayout.... Однако layoutAttributesForElementsInRect:, который предшествует ему, правильно определяет, что его атрибуты макета необходимы.

Так что же происходит? Некоторое понимание того, что происходит под капотом, было бы очень полезно... UICollectionView похоже на массивный черный ящик.


person Stuart    schedule 22.10.2013    source источник
comment
stackoverflow.com/questions/12649271/   -  person Arun_    schedule 31.10.2013
comment
Если iOS обнаружит, что переход не может быть плавным, т. Е. Этот сценарий, он будет использовать анимацию плавного перехода для любых ячеек, которые сталкиваются с существующими ячейками. Это задокументировано в видео WWDC на UICollectionViews в iOS7.   -  person Tim    schedule 31.10.2013
comment
@Arun_k Этот вопрос не имеет отношения к этому вопросу - они просят разъяснить, почему initial/finalLayout... вызываются при чередовании, и фактически они подтверждают, что добавление кода, как указано выше, предотвращает анимацию плавного затухания. Этот вопрос касается дополнительных ячеек, представленных после анимированного изменения границ.   -  person Stuart    schedule 03.11.2013
comment
@Jeff Спасибо, не могли бы вы указать название конкретного видео, пожалуйста? Я знаю об анимации кроссфейда по умолчанию, однако я понимаю, что она должна быть полностью настраиваемой с использованием методов initial/finalLayout.... Я не понимаю, почему появляющаяся ячейка не может плавно анимироваться, если задана начальная позиция.   -  person Stuart    schedule 03.11.2013
comment
Расширенные методы с динамикой UIKit и пользовательскими переходами с использованием контроллеров представления. developer.apple.com/wwdc/videos   -  person Tim    schedule 03.11.2013
comment
@Jeff Джефф Я так и не нашел подробностей в тех видео, на которые вы ссылались ... Я не думаю, что они упоминают повороты / кроссфейды?   -  person Stuart    schedule 29.01.2014
comment
вам удалось найти решение для этого? У меня похожая проблема, некоторые из моих ячеек не появляются. stackoverflow.com/questions/22413621/   -  person Frank    schedule 17.03.2014
comment
Любое решение для этого?   -  person Daniel Galasko    schedule 25.02.2015


Ответы (1)


Основываясь на ответ, на который ссылается Arun_k, кажется, что вам может понадобиться вернуть что-то отличное от initialLayoutAttributesForAppearingItemAtIndexPath:, кроме nil, для новой появляющейся ячейки. nil работает для ячеек, которые уже отображаются на экране, но может быть неправильным возвратом для новой ячейки. Возможно, вы можете поиграть с возвратом фиксированного значения UICollectionViewLayoutAttributes для всех ячеек в этом методе, чтобы увидеть, изменит ли это поведение анимации вновь вставленной ячейки, а затем продолжить оттуда.

Этот вопрос проливает еще больше света на эту проблему: initialLayoutAttributesForAppearingItemAtIndexPath запускается для всех видимых ячеек, а не только для вставленных ячейки

person Johannes Fahrenkrug    schedule 31.10.2013
comment
Спасибо за ответ. К сожалению, как я сказал в своем вопросе, возврат значения, отличного от нуля ([self layoutAttributesForItem...]), не имеет никакого значения, хотя регистрация возвращаемых значений показывает правильную начальную позицию для всех ячеек, включая новую появляющуюся ячейку. Я поиграю, как было предложено, и посмотрю, смогу ли я узнать больше. - person Stuart; 03.11.2013