iOS 仿咸鱼首页瓷片区动画

一、先直接展示效果:

xiaoguo.gif

二、逻辑思维:

我用的是UICollectionView,然后自定义collectionViewLayout布局文件,然后在滚动的时候获取布局信息,修改item大小,并重新布局以及偏移量的设置

三、直接上代码:

新建FirstCellZoomInLayout类,继承UICollectionViewFlowLayout

.h代码如下:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@protocol FirstCellZoomInLayoutDelegate <UICollectionViewDelegateFlowLayout>
//设置第一个item大小
- (CGSize)sizeForFirstCell;

@end

@interface FirstCellZoomInLayout : UICollectionViewFlowLayout
//代理
@property (nonatomic, weak) id<FirstCellZoomInLayoutDelegate> delegate;

@end

NS_ASSUME_NONNULL_END

.m代码如下:

#import "FirstCellZoomInLayout.h"

@interface FirstCellZoomInLayout()

@end

@implementation FirstCellZoomInLayout

- (void)prepareLayout {
    [super prepareLayout];
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;//设置滑动方向为水平滑动
}

/*
 获取所有的布局信息
 */
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *originalArr = [super layoutAttributesForElementsInRect:rect];
    UIEdgeInsets sectionInsets = [self.delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:0];
    CGSize itemSize = [self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    CGRect first = CGRectMake(sectionInsets.left + self.collectionView.contentOffset.x, sectionInsets.top + self.collectionView.contentOffset.y, itemSize.width, itemSize.height);
    //获取代理设置第一个cell大小
    CGSize firstCellSize = [self.delegate sizeForFirstCell];
    CGFloat totalOffset = 0;
    for (UICollectionViewLayoutAttributes *attributes in originalArr) {
        CGRect originFrame = attributes.frame;
        //判断两个矩形是否相交
        if (CGRectIntersectsRect(first, originFrame)) {
            //如果相交,获取两个矩形相交的区域
            CGRect insertRect = CGRectIntersection(first, originFrame);
            attributes.size = CGSizeMake(itemSize.width + (insertRect.size.width / itemSize.width) * (firstCellSize.width - itemSize.width), itemSize.height + (insertRect.size.width) / (itemSize.width) * (firstCellSize.height - itemSize.height));
            CGFloat currentOffsetX = attributes.size.width - itemSize.width;
            attributes.center = CGPointMake(attributes.center.x + totalOffset + currentOffsetX / 2, attributes.center.y);
            totalOffset = totalOffset + currentOffsetX;
        } else {
            if (CGRectGetMinX(originFrame) >= CGRectGetMaxX(first)) {
                attributes.center = CGPointMake(attributes.center.x + totalOffset, attributes.center.y);
            }
        }
    }
    return originalArr;
}
#pragma mark -- 当边界改变时,是否应该刷新布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return YES;
}
#pragma mark -- 设置滚动时的偏移量
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
    UIEdgeInsets sectionInsets = [self.delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:0];
    CGSize itemSize = [self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    CGFloat finalPointX = 0;
    NSInteger index = ceil(proposedContentOffset.x / (itemSize.width + self.minimumInteritemSpacing));
    finalPointX = (itemSize.width + self.minimumInteritemSpacing) * index;
    CGPoint finalPoint = CGPointMake(finalPointX, proposedContentOffset.y);
    return finalPoint;
}

四、使用:

1.在使用得VC导入头文件,并实现代理方法
#import "FirstCellZoomInLayout.h"-- <FirstCellZoomInLayoutDelegate>

2.创建CollectionView

FirstCellZoomInLayout *layout = [[FirstCellZoomInLayout alloc] init];
layout.delegate = self;
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];

3.实现代理方法:

#pragma mark - FirstCellZoomInLayoutDelegate
- (CGSize)sizeForFirstCell {
    return CGSizeMake(180, 100);
}

五、结束:

谢谢你的观看,感谢老铁点赞。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容