iOS開發-UICollectionView實現瀑布流
關于瀑布流的實現網上有很多種解法,自定義控件,TableView+ScrollView,UICollectionView是iOS6發布之后用于展示集合視圖,算起來已經發布三年左右了,不過知識點是不變的,集合視圖提供了一個更優雅的方式去展示圖片或者文字信息。UICollectionView與UITableView相似,UICollectionViewController與UITableViewController都負責視圖,存儲需要的數據,并且能處理數據源與委托協議。
簡單瀑布流
首先來看一個簡單的UICollectionView實現瀑布流的過程,熟悉之后就可以實現稍微實用的瀑布流:
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中設置一下數據源和代理:
self.collectionView.delegate=self; self.collectionView.dataSource=self; self.collectionView.backgroundColor=[UIColor whiteColor];
最終效果如下:
石工布局(瀑布流)
上面那種效果其實還是比較簡單的,很多情況下所有的單元格的寬度是一定的,只是高度不確定,這就是有些人說的定寬不定高,主要是從視覺上的美感來看,當然我們可以通過實現UICollectionViewDelegateFlowLayout去改變單元格大小:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ CGFloat height=100+(arc4random()%100); return CGSizeMake(100, height); }
通過效果我們可以發現,同一行的單元格的圓心所在的Y軸坐標都是一樣的:
石工布局(masonry layout)最早是Pinterest使用,石工簡單理解就是前面貼磚的時候每塊磚肯能是長方形的也可能正方形的,最終貼出來的效果是長方形或者正方形,國內的話基本上就稱為瀑布流,早先是Web網站上流行,現在在手機上看,有些Web甚至整個網站的內容都在一個瀑布流頁面,也有點審美疲勞的感覺。
這次先看下最終實現的效果:
這個應該算是最常見的布局模式了,這個的實現很簡單,為了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; }
效果演示: