這是我的嘗試。它可以工作,但由於這是我第一次嘗試自定義佈局,我相信有些事情可以改進。我製成UICollectionViewFlowLayout的子類,稱爲MultipleLineLayout與此代碼:
@implementation MultpleLineLayout {
NSInteger itemWidth;
NSInteger itemHeight;
}
-(id)init {
if (self = [super init]) {
itemWidth = 60;
itemHeight = 60;
}
return self;
}
-(CGSize)collectionViewContentSize {
NSInteger xSize = [self.collectionView numberOfItemsInSection:0] * (itemWidth + 20) + 60;
NSInteger ySize = [self.collectionView numberOfSections] * (itemHeight + 20) ;
return CGSizeMake(xSize, ySize);
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path {
UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];
NSInteger xValue;
if (path.row == 0) {
itemWidth = 120;
attributes.size = CGSizeMake(itemWidth,itemHeight);
xValue = itemWidth/2 + path.row * (itemWidth +20);
}else{
itemWidth = 60;
attributes.size = CGSizeMake(itemWidth,itemHeight);
xValue = itemWidth/2 + path.row * (itemWidth +20) + 60;
}
NSInteger yValue = itemHeight + path.section * (itemHeight +20);
attributes.center = CGPointMake(xValue, yValue);
return attributes;
}
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
NSInteger minRow = (rect.origin.x > 0)? rect.origin.x/(itemWidth +20) : 0; // need to check because bounce gives negative values for x.
NSInteger maxRow = rect.size.width/(itemWidth +20) + minRow;
NSMutableArray* attributes = [NSMutableArray array];
for(NSInteger i=0 ; i < self.collectionView.numberOfSections; i++) {
for (NSInteger j=minRow ; j < maxRow; j++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForItem:j inSection:i];
[attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
}
return attributes;
}
這是在視圖控制器的代碼:
#import "ViewController.h"
#import "MultpleLineLayout.h"
@interface ViewController()
@property (strong,nonatomic) UICollectionView *collectionView;
@property (strong,nonatomic) NSArray *theData;
@end
@implementation ViewController
- (void)viewDidLoad {
self.theData = @[@[@"Player 1",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20"], @[@"Player 2",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20"],@[@"Player 3",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20"],@[@"Player 4",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20"]];
MultpleLineLayout *layout = [[MultpleLineLayout alloc] init];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.view.backgroundColor = [UIColor blackColor];
[self.view addSubview:self.collectionView];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
[self.collectionView reloadData];
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return [self.theData[section] count];
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return [self.theData count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
[cell.contentView.subviews.lastObject removeFromSuperview]; //removes the label from a dequeued cell so we can make a new one of the right size.
UILabel *label;
if (indexPath.row == 0) {
label = [[UILabel alloc]initWithFrame:CGRectMake(10, 15, 100, 30)];
}else{
label = [[UILabel alloc]initWithFrame:CGRectMake(10, 15, 40, 30)];
}
label.backgroundColor = [UIColor yellowColor];
label.textAlignment = NSTextAlignmentCenter;
label.text = self.theData[indexPath.section][indexPath.row];
[cell.contentView addSubview:label];
cell.backgroundColor = [UIColor orangeColor];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *item = [collectionView cellForItemAtIndexPath:indexPath];
NSLog(@"%@",[(UILabel *)item.contentView.subviews.lastObject text]);
}
所以,我的數據被設置爲一個數組的數組,其中每個子陣列是一名球員和他的得分。這種佈局似乎確保每個玩家細胞都處於水平線上。我讓每一行的第一個單元格更大,以保存玩家的名字 - 我不確定處理這個大單元格的最佳方式是什麼。我硬編碼了一些數字,但這可能不是最好的方法。
我歡迎任何有待改進或修復的建議。
UICollectionView功能非常強大,但通常需要實現其大部分數據源/委託(更不用說有時提供UICollectionViewFlowLayout)來實現小型定製。你當然可以閱讀文檔,並學習使用一個強大的類,它可以在未來的項目中找到它的用途,或者將短路用於更專業的類。但有一點是肯定的,「可能收集視圖不是一個好用的API」並不是一個真實的陳述。 –
[這裏](http://rdcworld-iphone.blogspot.in/2013/03/uicollection-view-in-ios-6-tutorial.html)是收集視圖的簡單教程 – swiftBoy
我也在創建類似的東西。 – khunshan