最常見(jiàn)的是網(wǎng)上有很多商城中的瀑布流列表展示和高大上圖片瀏覽中會(huì)用到自定義的UICollectionViewFlowLayout,前者是屏幕上根據(jù)需求展示不同大小的UICollectionViewCell兩列或者三列粉私,錯(cuò)落排列顽腾,后者是展現(xiàn)出一種圖片立體環(huán)繞視覺(jué),前方圖片總是居中顯示诺核,兩側(cè)圖片比例要小抄肖,隨著顯現(xiàn)或者消失做放大或者縮小處理
最近,在實(shí)際項(xiàng)目中遇到一種類似后者圖片瀏覽的那種效果窖杀,但是每個(gè)UICollectionViewCell等大顯示漓摩,不做放大縮小處理。因?yàn)橹傲私膺^(guò)這種效果實(shí)現(xiàn)的大概機(jī)制入客,所以管毙,開(kāi)始以為會(huì)比較簡(jiǎn)單,可以后來(lái)發(fā)現(xiàn)自己錯(cuò)了桌硫,我先從網(wǎng)上找了demo夭咬,貼一下主要代碼,每個(gè)方法的作用我都加了備注
//重新設(shè)置collectionView的contentOffset,也就是每個(gè)cell的x值鞍泉,proposedContentOffset是實(shí)際按照設(shè)置的layout布局的偏移量皱埠,該方法重新設(shè)置實(shí)際需要的偏移量,當(dāng)然要根據(jù)collectionView的寬度咖驮,layout設(shè)置的itemSize以及sectionInsets等
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
proposedContentOffset.y = 0.0;
if (_isPagingEnabled) {
proposedContentOffset.x = [self PageMove:proposedContentOffset];
}else{
proposedContentOffset.x = [self SMove:proposedContentOffset velocity:velocity];
}
return proposedContentOffset;
}
//內(nèi)部參數(shù)根據(jù)自己實(shí)際需要設(shè)置边器,這就需要你的知識(shí)了
-(CGFloat)PageMove:(CGPoint)proposedContentOffset{
CGFloat set_x = proposedContentOffset.x;
if (set_x > _move_x) {
_move_x += SCREENWITH - 15 * 2;
}else if(set_x < _move_x){
_move_x -= SCREENWITH - 15 * 2;
}
set_x = _move_x;
return set_x;
}
-(CGFloat)SMove:(CGPoint)proposedContentOffset velocity :(CGPoint)velocity{
CGFloat offSetAdjustment = MAXFLOAT;
CGFloat horizontalCenter = (CGFloat) (proposedContentOffset.x + (self.collectionView.bounds.size.width / 2.0));
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray *array = [self layoutAttributesForElementsInRect:targetRect];
UICollectionViewLayoutAttributes *currentAttributes;
for (UICollectionViewLayoutAttributes *layoutAttributes in array)
{
if(layoutAttributes.representedElementCategory == UICollectionElementCategoryCell)
{
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offSetAdjustment))
{
currentAttributes = layoutAttributes;
offSetAdjustment = itemHorizontalCenter - horizontalCenter;
}
}
}
CGFloat nextOffset = proposedContentOffset.x + offSetAdjustment;
proposedContentOffset.x = nextOffset;
CGFloat deltaX = proposedContentOffset.x - self.collectionView.contentOffset.x;
CGFloat velX = velocity.x;
if(deltaX == 0.0 || velX == 0 || (velX > 0.0 && deltaX > 0.0) || (velX < 0.0 && deltaX < 0.0)) {
} else if(velocity.x > 0.0) {
for (UICollectionViewLayoutAttributes *layoutAttributes in array)
{
if(layoutAttributes.representedElementCategory == UICollectionElementCategoryCell)
{
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (itemHorizontalCenter > proposedContentOffset.x) {
proposedContentOffset.x = nextOffset + (currentAttributes.frame.size.width / 2) + (layoutAttributes.frame.size.width / 2);
break;
}
}
}
} else if(velocity.x <= 0.0) {
for (UICollectionViewLayoutAttributes *layoutAttributes in array)
{
if(layoutAttributes.representedElementCategory == UICollectionElementCategoryCell)
{
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (itemHorizontalCenter > proposedContentOffset.x) {
proposedContentOffset.x = nextOffset - ((currentAttributes.frame.size.width / 2) + (layoutAttributes.frame.size.width / 2));
break;
}
}
}
}
if (proposedContentOffset.x == -0.0) {
proposedContentOffset.x = 0.0;
}
return proposedContentOffset.x;
}
-(void)setPagingEnabled:(BOOL)isPagingEnabled{
_isPagingEnabled = isPagingEnabled;
}
static CGFloat const ActiveDistance = 350;
static CGFloat const ScaleFactor = 0.05;
//重寫該方法,返回需要的每個(gè)Cell的布局托修,在系統(tǒng)的基礎(chǔ)上做出需要的效果忘巧,這里就用大了放大縮小
-(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) {
// CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
// CGFloat normalizedDistance = distance / ActiveDistance;
// CGFloat zoom = 1 + ScaleFactor*(1 - ABS(normalizedDistance));
// attributes.transform3D = CATransform3DMakeScale(1.0, zoom, 1.0);
// attributes.zIndex = 1;
// }
return array;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
如上代碼,我開(kāi)始只是把放大縮小的效果注釋了睦刃,其實(shí)這個(gè)方法可以不要砚嘴,因?yàn)槲也恍枰獙?duì)cell做特殊處理,我以為居中顯示且沒(méi)有放大縮小,可是偏移量根本不是我想要的际长,為什么耸采,因?yàn)? (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity是需要根據(jù)自己設(shè)置的collectionView的寬度和itemSize等變量自己去計(jì)算這個(gè)偏移量的
我貌似在說(shuō)廢話。工育。虾宇。