创建自定义集合视图布局

时间:2014-08-11 22:28:35

标签: ios objective-c uicollectionview uicollectionviewlayout

我正在尝试创建一个类似下面的原理图的集合视图。中心项目始终具有“焦点”。并且更大,它有点像封面流程概念:

http://s13.postimg.org/n6vzil213/layout_schematic.png

我可以使用UICollectionViewFlowLayout来实现这一点,但是我希望底部单元格(3)设置较大的动画,而中间单元格(2)在我滚动时动画更小?我假设我需要使用滚动视图委托方法进行一些数学运算。

关于如何实现这一目标的任何想法?

1 个答案:

答案 0 :(得分:2)

只需继承UICollectionViewFlowLayout即可完成此操作。

以下是步骤:

  1. 创建UICollectionViewFlowLayout子类
  2. 覆盖shouldInvalidateLayoutForBoundsChange:并返回YES
  3. 覆盖layoutAttributesForElementsInRect:和layoutAttributesForItemAtIndexPath:。调用super实现来获取标准的FlowLayout值。
  4. 创建一种方法,来自步骤#3的方法调用它们会根据它们与集合视图中心的距离的距离来更改项目的布局属性。使用math为项目设置正确的itemSize / transform / 3D变换。
  5. 这是一个非常粗略的例子,如果没有正确的数学运算,那就是你要找的东西。

    @implementation MMLayout
    
    -(CGSize)itemSize
    {
        return CGSizeMake(200.0f, 200.0f);
    }
    
    -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
    {
        return YES;
    }
    
    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {
        NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
    
        for (UICollectionViewLayoutAttributes *atts in attributes) {
            [self scaleForPositionOfAttributes:atts];
        }
    
        return attributes;
    }
    
    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
    {
        UICollectionViewLayoutAttributes *atts = [super layoutAttributesForItemAtIndexPath:indexPath];
    
        [self scaleForPositionOfAttributes:atts];
    
        return atts;
    }
    
    - (void)scaleForPositionOfAttributes:(UICollectionViewLayoutAttributes *)attributes
    {
        CGFloat collectionViewHeight = CGRectGetHeight(self.collectionView.bounds);
        CGFloat collectionViewCenter = collectionViewHeight / 2.0f;
    
        CGFloat scaleForCenter = ABS(collectionViewCenter - (attributes.frame.origin.y - self.collectionView.contentOffset.y)) < 50.0f ? 1.3f : 0.7f;
        attributes.size = CGSizeMake(200.0f * scaleForCenter, 200.0f * scaleForCenter);
    }
    
    @end