2

我试图让一个简单的集合视图工作。基本上,我希望集合视图与数据库中的表完全一样,其中包含可以水平滚动的行和列。像这样的东西:

玩家 1 单元 1 单元 2 单元 3 单元 4 ... 单元 20

玩家 2 单元 1 单元 2 单元 3 单元 4 ... 单元 20

<----------- 滚动--------------->

我正在使用集合视图,因此我可以准确地确定玩家正在单击的单元格,并且与 tableview 相比,它似乎总体上会给我更大的灵活性。

问题是我无法在我的一生中让集合视图像我想要的那样显示。单元格垂直堆叠...示例(无法使它们保持在一行中并水平滚动以查看该行的其他列。示例...

玩家 1 细胞 1 细胞 2 细胞 3

单元 4 单元 6 单元 7 ...

玩家 2 细胞 1 细胞 2 细胞 4

单元格 4...

我开始认为,也许集合视图不是一个好的 api,也许我应该简单地使用一个 tableview。任何帮助将不胜感激。

4

3 回答 3

2

这是我的尝试。它有效,但由于这是我第一次尝试自定义布局,我确信可以做一些事情来改进它。我使用以下代码创建了一个名为 MultipleLineLayout 的 UICollectionViewFlowLayout 子类:

@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]);

}

所以,我的数据被设置为一个数组数组,每个子数组是一个球员和他的分数。这种布局似乎确实使每个玩家单元格保持在一条水平线上。我将每行的第一个单元格放大以保存球员姓名——我不确定处理这个较大单元格的最佳方法是什么。我已经硬编码了一些数字,但这可能不是最好的方法。

我欢迎任何改进或修复的建议。

于 2012-12-18T23:19:48.440 回答
0

UICollectionView 非常强大且易于扩展,因为它添加了一个新功能:UICollectionViewFlowLayout。恐怕您无法在 Cocoa 中默认实现所需的完美解决方案,但是在您的情况下将 UICollectionViewFlowLayout 扩展到新布局可能是蛇式布局,这很容易。

如果有任何帮助,也许您可​​以查看这个 github 网址:KMCollectionViewSnakeLayout以获得一些提示。这不是这样的风格:

Player 1 cell 1 cell 2 cell3

cell 4 cell 6 cell 7 ...

Player 2 cell 1 cell 2 cell4

cell 4...

但是是这样的风格:

Player 1 cell 1 cell 2 | Player 2 cell 1 cell 2

cell3 cell 4 cell 6    | cell3 cell 4 cell6

cell 7 ...             | cell7

花点时间阅读它或 Apple Doc,你会得到很多!

于 2012-12-19T07:12:26.303 回答
0

我个人没有使用过这个,但似乎在其他 SO 帖子上推荐:

https://github.com/TheVole/Horizo​​ntalTable

也许这可能比 a 更好用UICollectionView

(另见这篇文章:如何在 iPhone 上制作水平 UI 表格视图?

祝你好运!

于 2012-12-18T21:09:39.973 回答