iOS 不规则瀑布流

    iOS 自从出了UICollectionview之后,界面的样式可谓更加的多元化,对于一些较为复杂的界面UICollectionview都可以相对轻松的实现,而且由于其 FlowLayout 子类的存在,界面的布局更可谓是随心所欲,下面就来介绍下在处理图片中比较爱用到的瀑布流,我这里和一些其他人的方法不一样,我是重写了它的一个类来实现的瀑布流,那么废话不多说,直接上 Demo

  首先我们需要创建一个类,基于UICollectionViewLayout 然后重写系统的协议方法

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;

获取每个 item 的大小 ( 如果不重写的话 , 在当前的 .m 文件里得不到 size, 没有代理人去调用该方法得到 size)



  这里为.h的代码:

@protocol myCollectionFlowLayoutDelegate <NSObject>


//重写系统的协议方法 获取每个item的大小 (如果不重写的话,在当前的.m文件里得不到size,没有代理人去调用该方法得到size)

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;


@end



@interface myCollectionFlowlayout : UICollectionViewLayout


@property (nonatomic ,assign)id <myCollectionFlowLayoutDelegate>myCollectionFlowLayout;

@property (nonatomic ,retain)NSMutableArray *array;

@property (nonatomic ,assign)CGFloat maxHiget;

@property (nonatomic ,retain)UICollectionViewLayoutAttributes *attributes;


   下面为.m 里的代码:

//重写系统prepareLayout方法,准备布局item之前会调用

- (void)prepareLayout{

    

    [super prepareLayout];

    

    //重新设置滚动范围时用

    self.maxHiget = 0;

    //用来存放item的属性

    self.array = [NSMutableArray array];

    //设置每列item y坐标的初始值

    CGFloat LeftY = 60,MidY = 60,ReightY = 60;

    //计算contentView 第一步

    CGFloat maxLeft = 0,maxMid = 0 ,maxRight = 0;

   //获得当前section有多少个item(viewController的协议方法返回)

    NSInteger count = [self.collectionView numberOfItemsInSection:0];

    //设置每个item的属性

    for (int i = 0; i < count; i++) {

        //生成item下标

        NSIndexPath *index = [NSIndexPath indexPathForItem:i inSection:0];

        //获取协议返回的size

        CGSize itemSize = [self.myCollectionFlowLayout collectionView:self.collectionView layout:self sizeForItemAtIndexPath:index];

        //判断,先把不是第一列的item取出来

        if (i % 3 != 0) {

           //根据item下标取出每个item属性对象,通过它能设置itemframe

            self.attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:index];

           

            

            //设置默认的x坐标为0

            float offsetX = 0;

            if (i % 2 == 0) {

                //设置中间itemx130;

                offsetX = 130;

                //设置中间列itemframe

                self.attributes.frame = CGRectMake(offsetX, MidY, itemSize.width, itemSize.height);

                //记录中间所有item高度--->计算contentView 第二步

                maxMid = MidY + itemSize.height;

                //设置item中间的间距为5

                MidY += itemSize.height + 5;

                

                

            }else{

                //设置右边itemx255

                offsetX = 255;

                self.attributes.frame = CGRectMake(offsetX, ReightY, itemSize.width, itemSize.height);

                maxRight = ReightY + itemSize.height;

                //计算contentView 第三步

                ReightY += itemSize.height + 5;

                

            }

            //

            self.maxHiget = maxMid > maxRight ? maxMid +5 : maxRight + 5;

            //item属性存放到数组中

            [self.array addObject:self.attributes];

            

        }else{

//            //获取协议返回的size

//            CGSize itemSize = [self.myCollectionFlowLayout collectionView:self.collectionView layout:self sizeForItemAtIndexPath:index];

            //设置左边item属性

            self.attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:index];

            //直接把左边itemX设置为5

            float offsetX = 5;

            self.attributes.frame = CGRectMake(offsetX, LeftY, itemSize.width, itemSize.height);

            maxLeft = LeftY + itemSize.height;

            LeftY += itemSize.height + 5;

            self.maxHiget = self.maxHiget > LeftY ? self.maxHiget +5 : LeftY + 5;

            [self.array addObject:self.attributes];

            

        }

    }

    

}

//重写系统方法,初始的layout的外观将由该方法返回的UICollectionViewLayoutAttributes来决定


-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{

    

    NSMutableArray *Arr = [[NSMutableArray alloc]init];

    for (int i = 0; i < [self.array count]; i++) {

        UICollectionViewLayoutAttributes *att = [self.array objectAtIndex:i];

        //判断第二个rect是不是在第一个rect的范围之内


        if (CGRectIntersectsRect(rect, att.frame)) {

            [Arr addObject:att];

        }

    }

    return Arr;

    

}

//重新设置滚动范围ContentSize

- (CGSize)collectionViewContentSize

{

    NSLog(@"===%f",self.maxHiget);

    

    return CGSizeMake(self.collectionView.frame.size.width, self.maxHiget);

}


到这里,瀑布流里最为关键的我们已经完成了,接下来就是在 Colltroller 里来调用我们重写的类


创建一个 viewColltroller

.h 里的代码:


#import "myCollectionFlowlayout.h"

@interface ViewController : UIViewController<myCollectionFlowLayoutDelegate,UICollectionViewDataSource,UICollectionViewDelegate>

@property (nonatomic ,retain)NSMutableArray *allArr;

@property (nonatomic ,retain)UICollectionView *colletionView;

@end


.m 里的代码:

#import "ViewController.h"


@interface ViewController ()


@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    

    myCollectionFlowlayout *flowLayout = [[myCollectionFlowlayout alloc]init];

    flowLayout.myCollectionFlowLayout = self;

    

    self.allArr = [NSMutableArray array];

    

    self.colletionView = [[UICollectionView alloc]initWithFrame:[[UIScreen mainScreen]bounds] collectionViewLayout:flowLayout];

    self.colletionView.delegate = self;

    self.colletionView.dataSource = self;

    [self.view addSubview:self.colletionView];

    self.colletionView.backgroundColor = [UIColor blackColor];

    

    [self.colletionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"reuse"];

    


}


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

    NSLog(@"1111111111111");

    return 100;

    

}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    

    static NSString *cellIdentifier = @"reuse";

    

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

    cell.backgroundColor = [UIColor colorWithRed:1.000 green:0.677 blue:0.555 alpha:1.000];

    if (indexPath.row % 2 == 0 && indexPath.row % 3 != 0) {

        cell.backgroundColor = [UIColor colorWithRed:1.000 green:0.522 blue:0.625 alpha:1.000];

    }else if (indexPath.row % 3 == 0){

        

        cell.backgroundColor = [UIColor colorWithRed:0.944 green:1.000 blue:0.603 alpha:1.000];


    }

    return cell;

    

}


-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    

    return CGSizeMake(375/3 - 10, arc4random() % 201 + 160);

    

    

}


这样,我们就实现了两列不规则瀑布流了....







你可能感兴趣的:(ios,xcode,瀑布流)