Подтвердить что ты не робот

UICollectionView setLayout: анимированный: не сохраняется zIndex

Я заметил, что при вызове setLayout:animated в UICollectionView для переключения между двумя макетами, в настоящее время видимая ячейка не придерживается zIndex, ее атрибуты макета были установлены в layoutAttributesForItemAtIndexPath:.

Например, если бы я имел UICollectionView с UICollectionViewFlowLayout, установите его minimumLineSpacing на отрицательное число, чтобы ячейки перекрывались, а затем устанавливали zIndex на каждую ячейку выше, чем у предыдущей ячейки, то кажется, что ячейки укладываются снизу вверх.

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

4b9b3361

Ответ 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, он по-прежнему показывает ячейки в соответствии с обратным порядком, что каждое подвью будет добавлено к нему супер-представлением.