UICollectionView setLayout:animated: not preserving zIndex

前端 未结 7 1981
既然无缘
既然无缘 2021-02-01 20:12

I\'ve noticed that when calling setLayout:animated in a UICollectionView to switch between two layouts, the currently visible cell doesn\'t adhere to t

相关标签:
7条回答
  • 2021-02-01 20:39

    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;
    }
    
    0 讨论(0)
  • 2021-02-01 20:41

    I've managed to get the behaviour I'm after by using a combination grimfrog and Charlie Elliott's responses.

    Charlie Elliott's solution got the correct final outcome for the items in the collection view but there was still a snapping effect on the zIndex during the animation.

    grimfrog's solution provided the correct look but had the problem of the zIndex still being incorrect after the layout change, despite looking correct.

    The combination of the two, while not a great solution, does work and does use the supported transform and zIndex properties of the UICollectionViewLayoutAttributes

    In my layout, I have

    - (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;
    }
    

    I won't make this as the correct answer just yet as I'm sure there must be another way to solve this, but I'm interested to see if this solves the problem for others as well.

    0 讨论(0)
  • 2021-02-01 20:42

    Try setting the z-index in:

    - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
    - (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
    
    0 讨论(0)
  • 2021-02-01 20:46

    I have had the same problem. Switching the layout will disregard the zIndex for the cell.

    I have managed to make it "look right" by applying a translation on the z-axis like this:

    attributes.transform3D = CATransform3DMakeTranslation(0, 0, indexPath.row);
    

    But it is just a visual fix, if you try to click on the item you will realize that the zIndex is still wrong until it is recycled by scrolling it offscreen.

    0 讨论(0)
  • Using @sampage & @grimfrog answers as a starting point, I was able to get a similar situation working

    - (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: calls layoutAttributesForItemAtIndexPath: when generating the attribute array - so I only needed to include the zIndex and transform3D there.

    0 讨论(0)
  • 2021-02-01 20:55

    This bit me too. After several tests I realized that UICollectionView will force selected cells to be on top, regardless of the z-index.

    0 讨论(0)
提交回复
热议问题