标签:
自定义UICollectionView,主要会用到以下几个方法:
以苹果官方的lineLayout为例,这个是对UICollectionViewFlowLayout的扩充,
-(id)init { self = [super init]; if (self) { self.itemSize = CGSizeMake(ITEM_SIZE, ITEM_SIZE); self.scrollDirection = UICollectionViewScrollDirectionHorizontal; self.sectionInset = UIEdgeInsetsMake(200, 0.0, 200, 0.0);//上下边距 self.minimumLineSpacing = 50.0;//行间距 } return self; }
这里初始化一些信息。
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; }
因为滑动放大,故这里需要返回yes,实时刷新layout。
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { NSArray* array = [super layoutAttributesForElementsInRect:rect]; //可视rect CGRect visibleRect; visibleRect.origin = self.collectionView.contentOffset; visibleRect.size = self.collectionView.bounds.size; //设置item的缩放 for (UICollectionViewLayoutAttributes* attributes in array) { if (CGRectIntersectsRect(attributes.frame, rect)) { CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;//item到中心点的距离 CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;//距离除以有效距离得到标准化距离 //距离小于有效距离才生效 NSLog(@"%f",distance); if (ABS(distance) < ACTIVE_DISTANCE) { CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));//缩放率范围1~1.3,与标准距离负相关 attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);//x,y轴方向变换 //attributes.zIndex = 0; } } } return array; }
这里对item进行放大操作(因为该类是继承自UICollectionViewFlowLayout,苹果重写了该方法,所以调用super可以拿到当前rect范围内attributes,如果继承自UICollectionViewLayout,调用super是什么都拿不到的)。这里的思想就是:距离屏幕中心超过一定距离(假设200,自己设定)开始放大,CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;item中心到屏幕中心点距离占200的比例,
CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));
这样便得到放大的倍数。
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { //proposedContentOffset是没有对齐到网格时本来应该停下的位置 //计算出实际中心位置 CGFloat offsetAdjustment = MAXFLOAT; CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0); //取当前屏幕中的UICollectionViewLayoutAttributes 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; } } //返回调整好的point return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y); }
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity 这个方法简单理解可以当作是用来设置collectionView的偏移量的,计算当前屏幕哪个item中心点距离屏幕中心点近,就将该item拉到中心去。
个人理解,不对的地方还请见谅。
关于自定义UICollectionViewLayout的一点个人理解<一>
标签:
原文地址:http://www.cnblogs.com/CyanStone/p/5099056.html