集合视图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合视图相关的知识,希望对你有一定的参考价值。

集合视图是ios 6推出的新视图,克服了表视图中一行只能显示一个单元的缺陷。下面来简单看看怎么使用集合视图,一共有5个步骤,如下:

1.自定义单元
2.配置视图控制器
3.内容单元
4.实现流式布局
5.分区标题视图

接下来,看看每一步的操作。

自定义视图

继承UICollectionViewCell,定义自己的属性

ContentCell.h
```objc

import

@interface ContentCell : UICollectionViewCell
@property (strong, nonatomic) UILabel *label;
@property (copy, nonatomic) NSString *text;
+ (CGSize)sizeForContentString:(NSString *)s;
@end
```

ContentCell.m
```objc

import ContentCell.h

@implementation ContentCell

  • (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
    self.label = [[UILabel alloc] initWithFrame:self.contentView.bounds];
    self.label.opaque = NO;
    self.label.backgroundColor = [UIColor colorWithRed:0.8 green:0.9 blue:1 alpha:1];
    self.label.textColor = [UIColor blackColor];
    self.label.textAlignment = NSTextAlignmentCenter;
    self.label.font = [[self class] defaultFont];
    [self.contentView addSubview:self.label];
    }
    return self;
    }

  • (UIFont *)defaultFont{
    return [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
    }

  • (CGSize)sizeForContentString:(NSString *)s{
    CGSize maxSize = CGSizeMake(300, 1000);
    NSStringDrawingOptions opts = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    [style setLineBreakMode:NSLineBreakByWordWrapping];

    NSDictionary *attributes = @{ NSFontAttributeName:[self defaultFont],
    NSParagraphStyleAttributeName:style};
    CGRect rect = [s boundingRectWithSize:maxSize options:opts attributes:attributes context:nil];
    return rect.size;
    }

  • (NSString *)text{
    return self.label.text;
    }

  • (void)setText:(NSString *)text{
    self.label.text = text;
    CGRect newLabelFrame = self.label.frame;
    CGRect newContentFrame = self.contentView.frame;
    CGSize textSize = [[self class] sizeForContentString:text];
    newLabelFrame.size = textSize;
    newContentFrame.size = textSize;
    self.label.frame = newLabelFrame;
    self.contentView.frame = newContentFrame;
    }
    @end
    ```

配置视图控制器

这步跟表视图类似,初始化数据,初始化集合视图,注册Cell

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = NO;
    self.sections =
    @[
      @{ @"header" : @"First Witch",
         @"content" : @"Hey, when will the three of us meet up later?" },
      @{ @"header" : @"Second Witch",
         @"content" : @"When everything's straightened out." },
      @{ @"header" : @"Third Witch",
         @"content" : @"That'll be just before sunset." },
      @{ @"header" : @"First Witch",
         @"content" : @"Where?" },
      @{ @"header" : @"Second Witch",
         @"content" : @"The dirt patch." },
      @{ @"header" : @"Third Witch",
         @"content" : @"I guess we'll see Mac there." },
      ];
    
    // Register cell classes
    [self.collectionView registerClass:[ContentCell class] forCellWithReuseIdentifier:@"CONTENT"];
    [self.collectionView registerClass:[HeaderCell class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HEADER"];
    
    // Do any additional setup after loading the view.
    self.collectionView.backgroundColor = [UIColor whiteColor];
    
    UIEdgeInsets contentInset = self.collectionView.contentInset;
    contentInset.top = 20;
    [self.collectionView setContentInset:contentInset];
    
    //流式布局时会用到
    UICollectionViewLayout *layout = self.collectionView.collectionViewLayout;
    UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)layout;
    flow.sectionInset = UIEdgeInsetsMake(10, 20, 30, 20);
    
    flow.headerReferenceSize = CGSizeMake(100, 25);
}

内容单元

可以发现,到这一步为止,都跟表视图的操作类似

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return self.sections.count;
}


- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    NSArray *words = [self wordsInSection:section];
    return words.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *words = [self wordsInSection:indexPath.section];
    ContentCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CONTENT" forIndexPath:indexPath];
    cell.text = words[indexPath.row];
    // Configure the cell
    
    return cell;
}

实现流式布局

这里定义了每个单元的大小。

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout*)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *words = [self wordsInSection:indexPath.section];
    CGSize size = [ContentCell sizeForContentString:words[indexPath.row]];
    return size;
}

以下代码放在viewDidLoad中,用来控制单元之间的距离。

    //流式布局时会用到
    UICollectionViewLayout *layout = self.collectionView.collectionViewLayout;
    UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)layout;
    flow.sectionInset = UIEdgeInsetsMake(10, 20, 30, 20);

分区标题视图

我们可以定义集合视图的分区标题视图,实现更多的效果。

首先得定义一个Cell

HeaderCell.m
```objc

import HeaderCell.h

@implementation HeaderCell

  • (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
    self.label.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.8 alpha:1];
    self.label.textColor = [UIColor blackColor];
    }
    return self;
    }

  • (UIFont *)defaultFont{
    return [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
    }

@end
```

再使用以下代码进行设置。

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
    if ([kind isEqual:UICollectionElementKindSectionHeader]) {
        HeaderCell *cell = [self.collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"HEADER" forIndexPath:indexPath];
        cell.text = self.sections[indexPath.section][@"header"];
        return cell;
    }
    return nil;
}

另外,还需要在初始化时注册cell以及显示指定大小

    //注册headerCell
    [self.collectionView registerClass:[HeaderCell class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HEADER"];
    
    UICollectionViewLayout *layout = self.collectionView.collectionViewLayout;
    UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout *)layout;
    flow.sectionInset = UIEdgeInsetsMake(10, 20, 30, 20);
    //指定header的大小
    flow.headerReferenceSize = CGSizeMake(100, 25);

以上是关于集合视图的主要内容,如果未能解决你的问题,请参考以下文章

代码片段 - Golang 实现集合操作

laravel特殊功能代码片段集合

回收站视图未显示在片段中

如何从片段内的列表视图打开链接网址?

如何使列表视图出现在片段中?

如何从活动中更改片段中视图的可见性