關於瀑布流的實現網上有不少種解法,自定義控件,TableView+ScrollView,UICollectionView是iOS6發佈以後用於展現集合視圖,算起來已經發布三年左右了,不過知識點是不變的,集合視圖提供了一個更優雅的方式去展現圖片或者文字信息。UICollectionView與UITableView類似,UICollectionViewController與UITableViewController都負責視圖,存儲須要的數據,而且能處理數據源與委託協議。數組
首先來看一個簡單的UICollectionView實現瀑布流的過程,熟悉以後就能夠實現稍微實用的瀑布流:dom
1.故事板中拖拽一個UICollectionView放在視圖中,效果以下:佈局
2.新建一個繼承子UICollectionViewCell的子類MyCollectionViewCell,將單元格的Class選定爲MyCollectionViewCell,而且設置Identifier爲MyCell。優化
3.實現UICollectionViewDelegate,UICollectionViewDataSource,設置區域,設置區域中的Item個數,生成可複用的單元格:網站
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ return 1; } -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return 100; } -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ MyCollectionViewCell *myCell=[collectionView dequeueReusableCellWithReuseIdentifier: @"MyCell" forIndexPath:indexPath]; [myCell setBackgroundColor:[UIColor greenColor]]; return myCell; }
viewDidLoad中設置一下數據源和代理:atom
self.collectionView.delegate=self; self.collectionView.dataSource=self; self.collectionView.backgroundColor=[UIColor whiteColor];
最終效果以下:spa
上面那種效果其實仍是比較簡單的,不少狀況下全部的單元格的寬度是必定的,只是高度不肯定,這就是有些人說的定寬不定高,主要是從視覺上的美感來看,固然咱們能夠經過實現UICollectionViewDelegateFlowLayout去改變單元格大小:代理
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ CGFloat height=100+(arc4random()%100); return CGSizeMake(100, height); }
經過效果咱們能夠發現,同一行的單元格的圓心所在的Y軸座標都是同樣的:rest
石工佈局(masonry layout)最先是Pinterest使用,石工簡單理解就是前面貼磚的時候每塊磚肯能是長方形的也可能正方形的,最終貼出來的效果是長方形或者正方形,國內的話基本上就稱爲瀑布流,早先是Web網站上流行,如今在手機上看,有些Web甚至整個網站的內容都在一個瀑布流頁面,也有點審美疲勞的感受。code
此次先看下最終實現的效果:
這個應該算是最多見的佈局模式了,這個的實現很簡單,爲了Demo的效果沒有沒有采起任何優化措施,僅供入門參考,設置存儲全部高度的數組:
//存儲全部的高度的數組 @property (strong,nonatomic) NSMutableArray *heightArr;
將高度添加到數組中:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ CGFloat height=100+(arc4random()%160); [self.heightArr addObject:[NSString stringWithFormat:@"%f",height]]; return CGSizeMake(100, height); }
修改每一行單元格的位置:
// [myCell setBackgroundColor:[UIColor greenColor]]; // return myCell; //} -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ MyCollectionViewCell *myCell=[collectionView dequeueReusableCellWithReuseIdentifier: @"MyCell" forIndexPath:indexPath]; [myCell setBackgroundColor:[UIColor redColor]]; NSInteger remainder=indexPath.row%3; NSInteger currentRow=indexPath.row/3; CGFloat currentHeight=[self.heightArr[indexPath.row] floatValue]; CGFloat positonX=100*remainder+10*(remainder+1); CGFloat positionY=(currentRow+1)*10; for (NSInteger i=0; i<currentRow; i++) { NSInteger position=remainder+i*3; positionY+=[self.heightArr[position] floatValue]; } myCell.frame = CGRectMake(positonX, positionY,100,currentHeight) ; NSUInteger *randomNumber=arc4random_uniform(9); NSString *girlFilename = [NSString stringWithFormat:@"Girl%lu.jpg", (unsigned long)randomNumber]; UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:girlFilename]]; [myCell setBackgroundView:imageView]; return myCell; }
效果演示: