iOS流布局UICollectionView系列五——圓環布局的實作
一、引言
前邊的幾篇部落格,我們了解了UICollectionView的基本用法以及一些擴充,在不定高的瀑布流布局中,我們發現,可以通過設定具體的布局屬性類UICollectionViewLayoutAttributes來設定設定每個item的具體位置,我們可以再擴充一下,如果位置我們可以自由控制,那個布局我們也可以更加靈活,就比如建立一個如下的circleLayout:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SO0kTNmRmYlZmN5ImMwADO2QTZ0YmZ5ATMxYmMjFGMj9CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
這種布局方式在apple的官方文檔中也有介紹,是UICollectionView的一個應用示例。
二、設計一個圓環布局
接着我們以前的想法,依然時候随機顔色的色塊來表達我們的item,先自定義一個layout類,這個類繼承于UICollectionViewLayout,UICollectionLayout是一個布局抽象基類,我們要使用自定義的布局方式,必須将其子類化,可能你還記得,我們在進行瀑布流布局的時候使用過UICollectionViewFlowLayout類,這個類就是繼承于UICollectionViewLayout類,系統為我們實作好的一個布局方案。
@interface MyLayout : UICollectionViewLayout
//這個int值存儲有多少個item
@property(nonatomic,assign)int itemCount;
@end
我們需要重寫這個類的三個方法,來進行圓環布局的設定,首先是prepareLayout,為布局做一些準備工作,使用collectionViewContentSize來設定内容的區域大小,最後使用layoutAttributesForElementsInRect方法來傳回我們的布局資訊字典,這個前面瀑布流布局的思路是一樣的:
@implementation MyLayout
{
NSMutableArray * _attributeAttay;
}
-(void)prepareLayout{
[super prepareLayout];
//擷取item的個數
_itemCount = (int)[self.collectionView numberOfItemsInSection:0];
_attributeAttay = [[NSMutableArray alloc]init];
//先設定大圓的半徑 取長和寬最短的
CGFloat radius = MIN(self.collectionView.frame.size.width, self.collectionView.frame.size.height)/2;
//計算圓心位置
CGPoint center = CGPointMake(self.collectionView.frame.size.width/2, self.collectionView.frame.size.height/2);
//設定每個item的大小為50*50 則半徑為25
for (int i=0; i<_itemCount; i++) {
UICollectionViewLayoutAttributes * attris = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
//設定item大小
attris.size = CGSizeMake(50, 50);
//計算每個item的圓心位置
/*
.
. .
. . r
. .
.........
*/
//計算每個item中心的坐标
//算出的x y值還要減去item自身的半徑大小
float x = center.x+cosf(2*M_PI/_itemCount*i)*(radius-25);
float y = center.y+sinf(2*M_PI/_itemCount*i)*(radius-25);
attris.center = CGPointMake(x, y);
[_attributeAttay addObject:attris];
}
//設定内容區域的大小
-(CGSize)collectionViewContentSize{
return self.collectionView.frame.size;
//傳回設定數組
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
return _attributeAttay;
在viewController中代碼如下:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
MyLayout * layout = [[MyLayout alloc]init];
UICollectionView * collect = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, 320, 400) collectionViewLayout:layout];
collect.delegate=self;
collect.dataSource=self;
[collect registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellid"];
[self.view addSubview:collect];
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 10;
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellid" forIndexPath:indexPath];
cell.layer.masksToBounds = YES;
cell.layer.cornerRadius = 25;
cell.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
return cell;
如上非常簡單的一些邏輯控制,我們就實作哦圓環布局,随着item的多少,布局會自動調整,如果不是UICollectionView的功勞,實作這樣的功能,我們可能要寫上一陣子了^_^。