UICollectionView setLayout: анимированный: не сохраняется zIndex
Я заметил, что при вызове setLayout:animated
в UICollectionView
для переключения между двумя макетами, в настоящее время видимая ячейка не придерживается zIndex
, ее атрибуты макета были установлены в layoutAttributesForItemAtIndexPath:
.
Например, если бы я имел UICollectionView
с UICollectionViewFlowLayout
, установите его minimumLineSpacing
на отрицательное число, чтобы ячейки перекрывались, а затем устанавливали zIndex
на каждую ячейку выше, чем у предыдущей ячейки, то кажется, что ячейки укладываются снизу вверх.
Однако это ломается, если я устанавливаю макет на другой макет, а затем обратно на этот оригинальный макет. Это как если бы в настоящее время видимая ячейка не прослушивает zIndex и помещается поверх других ячеек. Если я прокручиваю ячейку за кадром, то обратно на нее находится в правильном месте.
Ответы
Ответ 1
У меня была та же проблема. При переключении макета будет игнорироваться zIndex для ячейки.
Мне удалось сделать его "правильным", применив перевод на оси z следующим образом:
attributes.transform3D = CATransform3DMakeTranslation(0, 0, indexPath.row);
Но это просто визуальное исправление, если вы попытаетесь щелкнуть элемент, который вы поймете, что zIndex по-прежнему ошибочен, пока он не будет переработан, прокручивая его за кадром.
Ответ 2
Мне удалось получить следующее поведение, используя комбинацию grimfrog и ответы Charlie Elliott.
Решение Charlie Elliott получило правильный конечный результат для элементов в представлении коллекции, но во время анимации все еще был эффект привязки к zIndex.
Решение grimfrog обеспечило правильный внешний вид, но проблема с zIndex по-прежнему была неправильной после изменения макета, несмотря на то, что она выглядела правильно.
Комбинация двух, хотя и не отличное решение, работает и использует поддерживаемые преобразования и свойства zIndex для UICollectionViewLayoutAttributes
В моем макете у меня есть
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
[attributes enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attributes, NSUInteger idx, BOOL *stop) {
attributes.zIndex = attributes.indexPath.item + 1;
}];
return attributes;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
attributes.transform3D = CATransform3DMakeTranslation(0, 0, attributes.indexPath.item);
return attributes;
}
Я пока не буду считать это правильным ответом, так как я уверен, что должен быть другой способ решить эту проблему, но мне интересно узнать, разрешает ли эта проблема и для других.
Ответ 3
Try:
// In UICollectionViewCell subclass
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
{
[super applyLayoutAttributes:layoutAttributes];
// Setting zPosition instead of relaying on
// UICollectionView zIndex management 'fixes' the issue
self.layer.zPosition = layoutAttributes.zIndex;
}
Ответ 4
Это тоже бит. После нескольких тестов я понял, что UICollectionView
заставит выбранные ячейки быть сверху, независимо от z-индекса.
Ответ 5
Попробуйте установить z-index в:
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
Ответ 6
Используя @sampage и @grimfrog ответы в качестве отправной точки, мне удалось получить аналогичную ситуацию, работающую
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path
{
UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];
attributes.zIndex = path.item;
attributes.transform3D = CATransform3DMakeTranslation(0, 0, path.item);
// other attribute settings
return attributes;
}
My layoutAttributesForElementsInRect:
вызывает layoutAttributesForItemAtIndexPath:
при создании массива атрибутов - поэтому мне нужно было включить туда zIndex и transform3D.
Ответ 7
У меня появилось другое обходное решение. Поскольку все ячейки принадлежат к одному супервину, вызов bringSubviewToFront :
при работе сока. В частности, просмотрев иерархию представления Debug View, хотя UICollectionViewLayout не отображает ячейки в соответствии с zIndex, он по-прежнему показывает ячейки в соответствии с обратным порядком, что каждое подвью будет добавлено к нему супер-представлением.