Liang's Blog

Dont worry,be happy.

CollectionView Details

| Comments

今天,真热啊。

看了看苹果官方工程LineLayout,记录下这段代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

    -(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray* array = [super layoutAttributesForElementsInRect:rect];
    CGRect visibleRect;
    visibleRect.origin = self.collectionView.contentOffset;
    visibleRect.size = self.collectionView.bounds.size;
    
    for (UICollectionViewLayoutAttributes* attributes in array) {
        if (CGRectIntersectsRect(attributes.frame, rect)) {
            CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
            CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;
            if (ABS(distance) < ACTIVE_DISTANCE) {
                CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));
                attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
                attributes.zIndex = 1;
            }
        }
    }
    return array;
}

对方法的看法

1
方法调用,通过判断当前item和collectionview可视区域两个的中心间距同item的宽度来进行对比,以决定是否进行transform3D变换。变幻的时候添加了一个比例因子ZOOM_FACTOR,使缩放不会太夸张。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (CGPoint)targetContentOffsetForProposedContentOffset: (CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    
    //proposedContentOffset是没有对齐到网格时本来应该停下的位置
    CGFloat offsetAdjustment = MAXFLOAT;
    CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0);
    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
    NSArray* array = [super layoutAttributesForElementsInRect:targetRect];
    
    //对当前屏幕中的UICollectionViewLayoutAttributes逐个与屏幕中心进行比较,找出最接近中心的一个
    for (UICollectionViewLayoutAttributes* layoutAttributes in array) {
        CGFloat itemHorizontalCenter = layoutAttributes.center.x;
        if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
            offsetAdjustment = itemHorizontalCenter - horizontalCenter;
        }
    }
    return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}

对方法的看法

1
2
与上个方法一样,需要求得可是区域的cgrect,通过该参数求出所有的UICollectionViewLayoutAttributes,然后用每个参数里的center和中心点求差比较,比较的算法就是如果当前差数比上一个差的绝对值小就记录下来。
最后返回的应该停下来的点,y不动,x加的当前记录的差值。

对UICollectionViewLayoutAttributes的看法

1
UICollectionViewLayoutAttributes记录了一个元素所有与布局相关联的参数,仅此而已。

原文链接:http://www.onevcat.com/2012/08/advanced-collection-view/

Comments