iOS - UICollectionViewController

iOS - UICollectionViewController

前言

    NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView
    @available(iOS 6.0, *)       public class UICollectionView : UIScrollView 

1、collectionView 的创建

  • Objective-C

    • ViewController.m

      • 遵守协议 UICollectionViewDataSource, UICollectionViewDelegate
          // 数据源初始化
      
              // 声明数据源
              @property(nonatomic, retain)NSMutableArray *myDataArray;
      
              myDataArray = [[NSMutableArray alloc] init];
      
              NSMutableArray *titleNameArray = [[NSMutableArray alloc] init];
              NSMutableArray *imageNameArray = [[NSMutableArray alloc] init];
      
              for (int i = 1; i <= 15; i++) {
      
                  [titleNameArray addObject:[NSString stringWithFormat:@"第 %i 个", i]];
                  [imageNameArray addObject:[NSString stringWithFormat:@"2_%i", i]];
              }
      
              [myDataArray addObject:titleNameArray];
              [myDataArray addObject:imageNameArray];
      
          // 网格视图初始化
      
              // 创建网格视图布局对象,可以设置滑动方向,cell 的间距等
              UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
      
              // 创建网格视图对象,必须有布局对象
              UICollectionView *collectionView = [[UICollectionView alloc] 
                                        initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, 
                                                                        self.view.bounds.size.height - 20) 
                                 collectionViewLayout:flowLayout];
      
              // 设置代理
              collectionView.dataSource = self;
              collectionView.delegate = self;
      
              // 将网格视图添加到屏幕视图
              [self.view addSubview:collectionView];
      
              // 注册自定义表格视图
              [collectionView registerClass:[myCollectionViewCell1 class] forCellWithReuseIdentifier:@"myCell"];
      
          // UICollectionView 协议方法
      
              // 设置网格数
              - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
      
                  return [[myDataArray objectAtIndex:0] count];
              }
      
              // 设置网格大小
              - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)
                  indexPath {
      
                  return CGSizeMake((self.view.bounds.size.width - 40) / 3, 170);
              }
      
              // 设置每个网格的内容
              - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
      
                  // 使用自定义 Cell 创建,cell 必须用注册的方式定义
                  myCollectionViewCell1 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
      
                  // 设置 Cell 中视图包含的内容
                  cell.nameLabel.text = [myDataArray[0] objectAtIndex:indexPath.item];
                  cell.iconImageView.image = [UIImage imageNamed:[myDataArray[1] objectAtIndex:indexPath.item]];
      
                  return cell;
              }
    • myCollectionViewCell.h

          @interface myCollectionViewCell1 : UICollectionViewCell
      
          @property(nonatomic, retain)UILabel *nameLabel;
          @property(nonatomic, retain)UIImageView *iconImageView;
      
          @end
    • myCollectionViewCell.m

          - (instancetype)initWithFrame:(CGRect)frame {
      
              self = [super initWithFrame:frame];
      
              if (self) {
      
                  // 创建标签视图
                  _nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 20)];
                  _nameLabel.backgroundColor = [UIColor orangeColor];
                  _nameLabel.textAlignment = NSTextAlignmentCenter;
                  [self.contentView addSubview:_nameLabel];
      
                  // 创建图片视图
                  _iconImageView = [[UIImageView alloc] 
                                             initWithFrame:CGRectMake(0, 20, self.bounds.size.width, 
                                                                             self.bounds.size.height - 20)];
                  [self.contentView addSubview:_iconImageView];
              }
              return self;
          }
  • Swift

    • ViewController.swift

      • 遵守协议 UICollectionViewDataSource, UICollectionViewDelegate
          // 数据源初始化
      
              // 声明数据源
              var dataArray:[[String]] = Array()
      
              var titleNameArray:[String] = Array()
              var imageNameArray:[String] = Array()
      
              for i in 1...15 {
      
                  titleNameArray.append("第 \(i) 个")
                  imageNameArray.append("2_\(i)")
              }
      
              dataArray.append(titleNameArray)
              dataArray.append(imageNameArray)
      
          // 网格视图初始化
      
              // 创建网格视图布局对象,可以设置滑动方向,cell 的间距等
              let flowLayout = UICollectionViewFlowLayout()
      
              // 创建网格视图对象,必须有布局对象
              let collectionView = UICollectionView(frame: CGRectMake(0, 20, self.view.bounds.size.width, 
                                                                             self.view.bounds.size.height - 20), 
                                     collectionViewLayout: flowLayout)
      
              // 设置代理
              collectionView.dataSource = self
              collectionView.delegate = self
      
              // 将网格视图添加到屏幕视图
              self.view.addSubview(collectionView)
      
              // 注册自定义表格视图
              collectionView.registerClass(myCollectionViewCell1.self, forCellWithReuseIdentifier: "myCell")
      
          // UICollectionView 协议方法
      
              // 设置网格数
              func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
      
                  return dataArray[0].count
              }
      
              // 设置网格大小
              func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath:                          NSIndexPath!) -> CGSize{
      
                  return CGSizeMake((self.view.bounds.size.width - 40) / 3, 170)
              }
      
              // 设置每个网格的内容,cell 必须用注册方式定义
              func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      
                  // 使用自定义 Cell 创建
                  let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath) as! myCollectionViewCell1
      
                  // 设置 Cell 视图的内容
                  cell.nameLabel.text = dataArray[0][indexPath.item]
                  cell.iconImageView.image = UIImage(named: dataArray[1][indexPath.item])
      
                  return cell
              }
    • myCollectionViewCell.swift

          class myCollectionViewCell1: UICollectionViewCell {
      
              var nameLabel:UILabel!
              var iconImageView:UIImageView!
      
              override init(frame: CGRect) {
      
                  super.init(frame: frame)
      
                  // 创建标签视图
                  nameLabel = UILabel(frame: CGRectMake(0, 0, self.frame.size.width, 20))
                  nameLabel.backgroundColor = UIColor.orangeColor()
                  nameLabel.textAlignment = NSTextAlignment.Center
                  self.contentView.addSubview(nameLabel)
      
                  // 创建图片视图
                  iconImageView = UIImageView(frame: CGRectMake(0, 20, self.frame.size.width, 
                                                                       self.frame.size.height - 20))
                  self.contentView.addSubview(iconImageView)
              }
          }

2、collectionView 的设置

  • Objective-C

        // 设置表格滑动方向
        /*
            UICollectionViewScrollDirectionVertical       垂直方向,默认
            UICollectionViewScrollDirectionHorizontal     水平方向
        */
        flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
    
        // 设置网格最小水平和垂直方向间距
        /*
            默认 10,也可以通过代理设置
        */
        flowLayout.minimumInteritemSpacing = 5;
        flowLayout.minimumLineSpacing = 30;
    
        // 设置网格背景颜色
        /*
            默认为黑色
        */
        collectionView.backgroundColor = [UIColor clearColor];
  • Swift

        // 设置表格滑动方向
        /*
            case Vertical     垂直方向,默认
            case Horizontal   水平方向
        */
        flowLayout.scrollDirection = UICollectionViewScrollDirection.Vertical
    
        // 设置网格最小水平和垂直方向间距
        /*
            默认 10,也可以通过代理设置
        */
        flowLayout.minimumInteritemSpacing = 5
        flowLayout.minimumLineSpacing = 30
    
        // 设置网格背景颜色
        /*
            默认为黑色
        */
        collectionView.backgroundColor = UIColor.clearColor()

3、自定义 Cell 的创建与引用

  • Objective-C

    • myCollectionViewCell.h

          @interface myCollectionViewCell1 : UICollectionViewCell
      
          @property(nonatomic, retain)UILabel *nameLabel;
          @property(nonatomic, retain)UIImageView *iconImageView;
      
          @end
    • myCollectionViewCell.m

          - (instancetype)initWithFrame:(CGRect)frame {
      
              self = [super initWithFrame:frame];
      
              if (self) {
      
                  // 创建标签视图
                  _nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 20)];
                  _nameLabel.backgroundColor = [UIColor orangeColor];
                  _nameLabel.textAlignment = NSTextAlignmentCenter;
                  [self.contentView addSubview:_nameLabel];
      
                  // 创建图片视图
                  _iconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 20, 
                                                     self.bounds.size.width, self.bounds.size.height - 20)];
                  [self.contentView addSubview:_iconImageView];
              }
              return self;
          }
    • ViewController.m

          // 注册自定义表格视图
          [collectionView registerClass:[myCollectionViewCell1 class] forCellWithReuseIdentifier:@"myCell"];
      
          // 设置网格大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)
          indexPath {
      
              return CGSizeMake((self.view.bounds.size.width - 40) / 3, 170);
          }
      
          // 设置每个网格的内容,cell 必须采用注册的方式自定义
          - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
      
              // 使用自定义 Cell 创建
              myCollectionViewCell1 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
      
              // 设置自定义 Cell 中视图包含的内容
              cell.nameLabel.text = [myDataArray[0] objectAtIndex:indexPath.item];
              cell.iconImageView.image = [UIImage imageNamed:[myDataArray[1] objectAtIndex:indexPath.item]];
      
              return cell;
          }
  • Swift

    • myCollectionViewCell.swift

          class myCollectionViewCell1: UICollectionViewCell {
      
              var nameLabel:UILabel!
              var iconImageView:UIImageView!
      
              override init(frame: CGRect) {
      
                  super.init(frame: frame)
      
                  // 创建标签视图
                  nameLabel = UILabel(frame: CGRectMake(0, 0, self.frame.size.width, 20))
                  nameLabel.backgroundColor = UIColor.orangeColor()
                  nameLabel.textAlignment = NSTextAlignment.Center
                  self.contentView.addSubview(nameLabel)
      
                  // 创建图片视图
                  iconImageView = UIImageView(frame: CGRectMake(0, 20, self.frame.size.width, 
                                                                       self.frame.size.height - 20))
                  self.contentView.addSubview(iconImageView)
              }   
          }
    • ViewController.swift

          // 注册自定义表格视图
          collectionView.registerClass(myCollectionViewCell1.self, forCellWithReuseIdentifier: "myCell")
      
          // 设置网格大小
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) ->             CGSize{
      
              return CGSizeMake((self.view.bounds.size.width - 40) / 3, 170)
          }
      
          // 设置每个网格的内容,cell 必须用注册方式定义
          func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      
          // 使用自定义 Cell 创建
          let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath) as! myCollectionViewCell1   
      
              // 设置 Cell 视图的内容
              cell.nameLabel.text = dataArray[0][indexPath.item]
              cell.iconImageView.image = UIImage(named: dataArray[1][indexPath.item])
      
              return cell
          }

4、xib 自定义 Cell 的创建与引用

  • Objective-C

    • myCollectionViewCell.xib

    CollectionView1

    • myCollectionViewCell.h

          @interface myCollectionViewCell : UICollectionViewCell
      
          @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
          @property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
      
          @end
    • ViewController.m

          // 注册自定义表格视图
          [collectionView registerNib:[UINib nibWithNibName:@"myCollectionViewCell3" bundle:nil] forCellWithReuseIdentifier:@"xibCell"];
      
          // 设置网格大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)
          indexPath {
      
              return CGSizeMake(100, 170);
          }
      
          // 设置每个网格的内容,cell 必须采用注册的方式自定义
          - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
      
              // 使用自定义 Cell 创建
              myCollectionViewCell3 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"xibCell" forIndexPath:indexPath];
      
              // 设置自定义 Cell 中视图包含的内容
              cell.nameLabel.text = [dataArray[0] objectAtIndex:indexPath.item];
              cell.iconImageView.image = [UIImage imageNamed:[dataArray[1] objectAtIndex:indexPath.item]];
      
              return cell;
          }
  • Swift

    • myCollectionViewCell.xib

    CollectionView1

    • myCollectionViewCell.swift

          class myCollectionViewCell: UICollectionViewCell {
      
              @IBOutlet weak var nameLabel: UILabel!
              @IBOutlet weak var iconImageView: UIImageView!
          }
    • ViewController.swift

          // 注册自定义表格视图
          collectionView.registerNib(UINib(nibName: "myCollectionViewCell3", bundle: nil), forCellWithReuseIdentifier: "xibCell")
      
          // 设置网格大小
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) ->             CGSize{
      
              return CGSizeMake(100, 170)
          }
      
          // 设置每个网格的内容,cell 必须用注册的方式定义
          func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      
              // 使用自定义 Cell 创建
              let cell = collectionView.dequeueReusableCellWithReuseIdentifier("xibCell", forIndexPath: indexPath) as! myCollectionViewCell3
      
              // 设置 Cell 视图内容
              cell.nameLabel.text = dataArray[0][indexPath.item]
              cell.iconImageView.image = UIImage(named: dataArray[1][indexPath.item])
      
              return cell
          }

5、自定义 分段头尾的创建与引用

  • Objective-C

    • myHeaderFooterView.h

          @interface myHeaderFooterView : UICollectionReusableView
      
          @property(nonatomic, retain)UILabel *nameLabel;
      
          @end
    • myHeaderFooterView.m

          - (instancetype)initWithFrame:(CGRect)frame {
      
              self = [super initWithFrame:frame];
      
              if (self) {
      
                  _nameLabel = [[UILabel alloc] initWithFrame:self.bounds];
                  _nameLabel.textAlignment = NSTextAlignmentCenter;
                  _nameLabel.backgroundColor = [UIColor lightGrayColor];
      
                  [self addSubview:_nameLabel];
              }
              return self;
          }
    • ViewController.m

          // 注册分段头视图
          [collectionView registerClass:[myHeaderFooterView1 class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
      
          // 注册分段尾视图
          [collectionView registerClass:[myHeaderFooterView1 class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer"];
      
          // 设置分段头大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)
          section {
      
              /*
                  width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
              */
              return CGSizeMake(20, 30);
          }
      
          // 设置分段尾大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)
          section {
      
              /*
                  width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
              */
              return CGSizeMake(20, 30);
          }
      
          // 设置分段头尾的内容
          - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)
          indexPath {
      
              // collectionView 分段头尾的设置注册复用
              myHeaderFooterView1 *view = nil;
      
              // 分段头
              if (kind == UICollectionElementKindSectionHeader) {
      
                  // 创建分段头视图
                  view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath];
      
                  // 设置分段头的内容
                  view.nameLabel.text = [NSString stringWithFormat:@"第 %ld 段 Header", indexPath.section];
              }
              // 分段尾
              else {                                                                                                      
      
                  // 创建分段尾视图
                  view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer" forIndexPath:indexPath];
      
                  // 设置分段尾视图的内容
                  view.nameLabel.text = [NSString stringWithFormat:@"第 %ld 段结束 Footer", indexPath.section];
              }
      
              return view;
          }
  • Swift

    • myHeaderFooterView.swift

          class myHeaderFooterView: UICollectionReusableView {
      
              var nameLabel:UILabel!
      
              override init(frame: CGRect) {
      
                  super.init(frame: frame)
      
                  nameLabel = UILabel(frame: self.bounds)
                  nameLabel.textAlignment = NSTextAlignment.Center
                  nameLabel.backgroundColor = UIColor.lightGrayColor()
      
                  self.addSubview(nameLabel)
              }
          }
    • ViewController.swift

          // 注册分段头视图
          collectionView.registerClass(myHeaderFooterView1.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "header")
      
          // 注册分段尾视图
          collectionView.registerClass(myHeaderFooterView1.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "footer")
      
          // 设置分段头大小
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, referenceSizeForHeaderInSection:section) -> CGSize             {
      
              /*
                  width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
              */
      
              return CGSizeMake(20, 30)
          }
      
          // 设置分段尾大小
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, referenceSizeForFooterInSection:section) -> CGSize         {
      
              /*
                  width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
              */
      
          return CGSizeMake(20, 30)
          }
      
          // 设置分段头尾的内容
          func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) ->                            UICollectionReusableView {
      
              var view:myHeaderFooterView1!
      
              // 分段头
              if kind == UICollectionElementKindSectionHeader {
      
                  // 创建分段头视图
                  view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "header", forIndexPath:indexPath) as! myHeaderFooterView1
      
                  // 设置分段头的内容
                  view.nameLabel.text = "第 \(indexPath.section) 段 Header"
              }
              // 分段尾
              else {
                  // 创建分段尾视图
                  view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionFooter, withReuseIdentifier: "footer", forIndexPath:indexPath) as! myHeaderFooterView1
      
                  // 设置分段尾视图的内容
                  view.nameLabel.text = "第 \(indexPath.section) 段 Footer"
              }
      
              return view
          }

6、xib 自定义 分段头尾的创建与引用

  • Objective-C

    • myHeaderFooterView.xib

      CollectionView2

    • myHeaderFooterView.h

          @interface myHeaderFooterView : UICollectionReusableView
      
          @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
      
          @end
    • ViewController.m

          // 注册分段头视图
          [collectionView registerNib:[UINib nibWithNibName:@"myHeaderFooterView2" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"xibHeader"];
      
          // 注册分段尾视图
          [collectionView registerNib:[UINib nibWithNibName:@"myHeaderFooterView2" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"xibFooter"];
      
          // 设置分段头大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
      
              /*
                  width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
              */
              return CGSizeMake(20, 30);
          }
      
          // 设置分段尾大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
      
              /*
                  width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
              */
              return CGSizeMake(20, 30);
          }
      
          // 设置分段头尾的内容
          - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
      
              // collectionView 分段头尾的设置注册复用
              myHeaderFooterView2 *view = nil;
      
              // 分段头
              if (kind == UICollectionElementKindSectionHeader) {
      
              // 创建分段头视图
              view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"xibHeader" forIndexPath:indexPath];
      
                  // 设置分段头的内容
                  view.nameLabel.text = [NSString stringWithFormat:@"第 %ld 段 xibHeader", indexPath.section];
              }
              // 分段尾
              else {
      
                  // 创建分段尾视图
                  view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"xibFooter" forIndexPath:indexPath];
      
                  // 设置分段尾视图的内容
                  view.nameLabel.text = [NSString stringWithFormat:@"第 %ld 段结束 xibFooter", indexPath.section];
              }
      
              return view;
          }
  • Swift

    • myHeaderFooterView.xib

      CollectionView2

    • myHeaderFooterView.swift

          class myHeaderFooterView: UICollectionReusableView {
      
              @IBOutlet weak var nameLabel: UILabel!
          }
    • ViewController.swift

          // 注册分段头视图
          collectionView.registerNib(UINib(nibName: "myHeaderFooterView2", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "xibHeader")
      
          // 注册分段尾视图
          collectionView.registerNib(UINib(nibName: "myHeaderFooterView2", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter,                                                withReuseIdentifier: "xibFooter")
      
          // 设置分段头大小
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, referenceSizeForHeaderInSection:section) -> CGSize {
      
              /*
                  width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
              */
      
              return CGSizeMake(20, 30)
          }
      
          // 设置分段尾大小
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, referenceSizeForFooterInSection:section) -> CGSize {
      
              /*
                  width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
              */
      
              return CGSizeMake(20, 30)
          }
      
          // 设置分段头尾的内容
      
          func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
      
              var view:myHeaderFooterView2!
      
              // 分段头
              if kind == UICollectionElementKindSectionHeader {
      
                  // 创建分段头视图
                  view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "xibHeader", forIndexPath:indexPath) as! myHeaderFooterView2
      
                  // 设置分段头的内容
                  view.nameLabel.text = "第 \(indexPath.section) 段 Header"
              }
              // 分段尾
              else {
      
                  // 创建分段尾视图
                  view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionFooter, withReuseIdentifier: "xibFooter", forIndexPath:indexPath) as! myHeaderFooterView2
      
                  // 设置分段尾视图的内容
                  view.nameLabel.text = "第 \(indexPath.section) 段 Footer"                                            
              }
      
              return view
          }

7、自定义布局风格

  • Objective-C

    • CustomLayout.h

          @interface CustomLayout : UICollectionViewLayout
    • CustomLayout.m

          /*
              简单定义了一个 section 的布局
          */
      
          @implementation CustomLayout
      
          // 设置网格视图的大小
          - (CGSize)collectionViewContentSize {
      
              // 每行显示 3 个图标,1大2小
              return CGSizeMake(self.collectionView.bounds.size.width, [self.collectionView numberOfItemsInSection:0 / 3] * 200 + 200);
          }
      
          // 设置单元格的位置属性
          - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
      
              NSMutableArray *attributesArray = [[NSMutableArray alloc] init];
      
              NSUInteger cellCount = [self.collectionView numberOfItemsInSection:0];
      
              for (int i = 0; i < cellCount; i++) {
      
                  UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
      
                  [attributesArray addObject:attributes];
              }
              return attributesArray;
          }
      
          // 设置单元格的位置与大小
          - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
      
              // 获取当前单元格布局属性
              UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
      
              // 单元格边长
              CGFloat largeCellSide = 200;
              CGFloat smallCellSide = 100;
      
              // 单元格间距
              //    NSUInteger itemSpacing = 2;
              NSUInteger lineSpacing = 5;
      
              // 边距
              UIEdgeInsets insets = UIEdgeInsetsMake(2, 20, 2, 20);
      
              // 当前行数
              /*
                  每行显示 3 个图片,1 大 2 小
              */
              NSInteger line = indexPath.item / 3;
      
              // 当前行的 Y 坐标
              CGFloat lineOriginY = insets.top + largeCellSide * line + lineSpacing * line;
      
              // 右侧单元格 X 坐标
              /*
                  这里按左右对齐,所以中间空隙大
              */
              CGFloat rightLargeX = self.collectionView.bounds.size.width - largeCellSide - insets.right;
              CGFloat rightSmallX = self.collectionView.bounds.size.width - smallCellSide - insets.right;
      
              // 每行 2 个图片,2 行循环一次,一共 6 种位置
              if (indexPath.item % 6 == 0) {
      
                  attribute.frame = CGRectMake(insets.left, lineOriginY, largeCellSide, largeCellSide);
              }
              else if (indexPath.item % 6 == 1) {
      
                  attribute.frame = CGRectMake(rightSmallX, lineOriginY, smallCellSide, smallCellSide);
              }
              else if (indexPath.item % 6 == 2) {
      
                  attribute.frame = CGRectMake(rightSmallX, lineOriginY + smallCellSide + insets.top, smallCellSide, smallCellSide);
              }
              else if (indexPath.item % 6 == 3) {
      
                  attribute.frame = CGRectMake(insets.left, lineOriginY, smallCellSide, smallCellSide);
              }
              else if (indexPath.item % 6 == 4) {
      
                  attribute.frame = CGRectMake(insets.left, lineOriginY + smallCellSide + insets.top, smallCellSide, smallCellSide);
              }
              else if (indexPath.item % 6 == 5) {
      
                  attribute.frame = CGRectMake(rightLargeX, lineOriginY, largeCellSide, largeCellSide);
              }
      
              return attribute;
          }
    • ViewController.m

          // 数据源初始化
      
              // 声明数据源
              @property(nonatomic, retain)NSMutableArray *dataArray;
      
              dataArray = [NSMutableArray arrayWithObjects:   @{@"name":@"Swift" , @"pic":@"swift.png" },
                          @{@"name":@"OC"    , @"pic":@"oc.jpg"    },
                          @{@"name":@"Java"  , @"pic":@"java.png"  },
                          @{@"name":@"PHP"   , @"pic":@"php.jpeg"  },
                          @{@"name":@"JS"    , @"pic":@"js.jpeg"   },
                          @{@"name":@"HTML"  , @"pic":@"html.jpeg" },
                          @{@"name":@"Ruby"  , @"pic":@"ruby.png"  }, nil];
      
          // 网格视图初始化
      
              // 声明网格视图
              @property(nonatomic, retain)UICollectionView *myCollectionView;
      
              CustomLayout *layout = [[CustomLayout alloc] init];
      
              myCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height - 20) collectionViewLayout:layout];
      
              // 默认背景是黑色和 label 一致
              myCollectionView.backgroundColor = [UIColor whiteColor];
              myCollectionView.delegate = self;
              myCollectionView.dataSource = self;
      
              // 注册 CollectionViewCell
              [myCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"myCell"];
      
              [self.view addSubview:myCollectionView];
      
          // UICollectionView 协议方法
      
              // 设置行数
              - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
      
                  return dataArray.count;
              }
      
              // 设置网格显示的内容
              - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
      
                  // 创建 cell
                  UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
      
                  // 创建自定义 cell 视图
                  UIImageView *imageView = [[UIImageView alloc] initWithFrame:cell.bounds];
                  imageView.image = [UIImage imageNamed:dataArray[indexPath.item][@"pic"]];
                  [cell addSubview:imageView];
      
                  UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, cell.bounds.size.width, 20)];
                  label.text = dataArray[indexPath.item][@"name"];
                  label.textAlignment = NSTextAlignmentCenter;
                  [cell addSubview:label];
      
                  return cell;
              }
  • Swift

    • CustomLayout.swift

          /*
              简单定义了一个 section 的布局
          */
      
          class CustomLayout: UICollectionViewLayout
      
          // 设置网格视图的大小
          override func collectionViewContentSize() -> CGSize {
      
              // 每行显示 3 个图标,1大2小
              return CGSizeMake(collectionView!.bounds.size.width, CGFloat((collectionView!.numberOfItemsInSection(0) / 3) * 200 + 200))
          }
      
          // 设置单元格的位置属性
          override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
      
              var attributesArray = Array<UICollectionViewLayoutAttributes>()
      
              let cellCount = self.collectionView!.numberOfItemsInSection(0)
      
              for i in 0..<cellCount {
      
                  let attributes = self.layoutAttributesForItemAtIndexPath(NSIndexPath(forItem: i, inSection: 0))
      
                  attributesArray.append(attributes!)
              }
      
              return attributesArray
          }
      
          // 设置单元格的位置与大小
          override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
      
              // 获取当前单元格布局属性
              let attribute = UICollectionViewLayoutAttributes(forCellWithIndexPath:indexPath)
      
              // 单元格边长
              let largeCellSide = CGFloat(200)
              let smallCellSide = CGFloat(100)
      
              // 单元格间距
              let itemSpacing = 2
              let lineSpacing = 5
      
              // 边距
              let insets = UIEdgeInsetsMake(2, 20, 2, 20)
      
              // 当前行数
              /*
                  每行显示 3 个图片,1 大 2 小
              */
              let line = indexPath.item / 3
      
              // 当前行的 Y 坐标
              let lineOriginY = insets.top + largeCellSide * CGFloat(line) + CGFloat(lineSpacing * line)
      
              // 右侧单元格 X 坐标
              /*
                  这里按左右对齐,所以中间空隙大
              */
              let rightLargeX = collectionView!.bounds.size.width - largeCellSide - insets.right
              let rightSmallX = collectionView!.bounds.size.width - smallCellSide - insets.right
      
              // 每行 2 个图片,2 行循环一次,一共 6 种位置
              if (indexPath.item % 6 == 0) {
      
                  attribute.frame = CGRectMake(insets.left, lineOriginY, largeCellSide, largeCellSide)
              }
              else if (indexPath.item % 6 == 1) {
      
                  attribute.frame = CGRectMake(rightSmallX, lineOriginY, smallCellSide, smallCellSide)
              }
              else if (indexPath.item % 6 == 2) {
      
                  attribute.frame = CGRectMake(rightSmallX, lineOriginY + smallCellSide + insets.top, smallCellSide, smallCellSide)
              }
              else if (indexPath.item % 6 == 3) {
      
                  attribute.frame = CGRectMake(insets.left, lineOriginY, smallCellSide, smallCellSide)
              }
              else if (indexPath.item % 6 == 4) {
      
                  attribute.frame = CGRectMake(insets.left, lineOriginY + smallCellSide + insets.top, smallCellSide, smallCellSide)
              }
              else if (indexPath.item % 6 == 5) {
      
                  attribute.frame = CGRectMake(rightLargeX, lineOriginY, largeCellSide, largeCellSide)
              }
      
              return attribute
          }
    • ViewController.swift

          // 数据源初始化
      
              // 声明数据源
              var dataArray:[[String:String]] = Array()
      
              dataArray = [
      
                  ["name":"Swift" , "pic":"swift.png" ],
                  ["name":"OC"    , "pic":"oc.jpg"    ],
                  ["name":"Java"  , "pic":"java.png"  ],
                  ["name":"PHP"   , "pic":"php.jpeg"  ],
                  ["name":"JS"    , "pic":"js.jpeg"   ],
                  ["name":"HTML"  , "pic":"html.jpeg" ],
                  ["name":"Ruby"  , "pic":"ruby.png"  ]
              ]
      
          // 网格视图初始化
      
              var myCollectionView:UICollectionView!
      
          // 声明网格视图
      
              let layout = CustomLayout()
      
              myCollectionView = UICollectionView(frame: CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height - 20), 
                                   collectionViewLayout:layout)
      
              // 默认背景是黑色和 label 一致
              myCollectionView.backgroundColor = UIColor.whiteColor()
              myCollectionView.delegate = self
              myCollectionView.dataSource = self
      
              // 注册 CollectionViewCell
              myCollectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "myCell")
      
              self.view.addSubview(myCollectionView)
      
          // UICollectionView 协议方法
      
              // 设置行数
              func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
      
                  return dataArray.count
              }
      
              // 设置网格显示的内容
              func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      
                  // 创建 cell
                  let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath)
      
                  // 创建自定义 cell 视图
      
                  let imageView = UIImageView(frame: cell.bounds)
                  imageView.image = UIImage(named: dataArray[indexPath.item]["pic"]!)
                  cell.addSubview(imageView)
      
                  let label = UILabel(frame:CGRectMake(0, 5, cell.bounds.size.width, 20))
                  label.text = dataArray[indexPath.item]["name"]
                  label.textAlignment = NSTextAlignment.Center
                  cell.addSubview(label)
      
                  return cell
              }

8、UICollectionView 协议方法

  • 需遵守协议 UICollectionViewDataSource, UICollectionViewDelegate,并设置代理

  • Objective-C

    • 分段、网格 设置

          // 设置分段数
          - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
      
              return 3;
          }
      
          // 设置网格数
          - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
      
              return 15;
          }
      
          // 设置网格大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
      
              return CGSizeMake(100, 170);
          }
      
          // 设置每个网格的内容
          - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
      
              /*
                  cell 必须采用注册的方式自定义
              */
      
              return cell;
          }
    • 网格间距设置

          // 设置最小网格间距
          - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
      
              /*
                  垂直滑动时,系统会根据屏幕宽度和网格(cell)的宽度在大于等于最小网格(cell)间距的范围内自动调整。
                  水平滑动时,系统会根据屏幕高度和网格(cell)的高度在大于等于最小网格(cell)间距的范围内自动调整。
              */
      
              return 10;
          }
      
          // 设置最小行间距
          - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
      
              return 10;
          }
      
          // 设置分段周边距
          - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
      
              // 上,左,下,右
              return UIEdgeInsetsMake(20, 10, 20, 10);
          }
    • 分段头尾 设置

          // 设置分段头大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
      
              /*
                  width 为水平滑动时的间距有效,height 为垂直滑动时的间距有效
              */
      
              return CGSizeMake(20, 30);
          }
      
          // 设置分段尾大小
          - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
      
              /*
                  width 为水平滑动时的间距有效,height 为垂直滑动时的间距有效
              */
      
              return CGSizeMake(20, 30);
          }
      
          // 设置分段头尾视图
          - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
      
              return myView;
          }
    • 网格点击 设置

          // 网格点击
          - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
      
          }
      
          // 网格取消点击,点击另一个表格的时候触发
          - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
      
          }
  • Swift

    • 分段、网格 设置

          // 设置分段数
          func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
      
              return 3
          }
      
          // 设置网格数
          func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
      
              return 15
          }
      
          // 设置网格大小
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {
      
              return CGSizeMake(100, 170)
          }
      
          // 设置每个网格的内容
          func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      
              /*
                  cell 必须采用注册的方式自定义
              */
      
              return cell
          }
    • 网格间距 设置

          // 设置最小网格间距
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, minimumInteritemSpacingForSectionAtIndex:section) -> CGFloat {
      
              /*
                  垂直滑动时,系统会根据屏幕宽度和网格(cell)的宽度在大于等于最小网格(cell)间距的范围内自动调整。
                  水平滑动时,系统会根据屏幕高度和网格(cell)的高度在大于等于最小网格(cell)间距的范围内自动调整。
              */
      
              return 10
          }
      
          // 设置最小行间距
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, minimumLineSpacingForSectionAtIndex:section) -> CGFloat {
      
              return 50
          }
      
          // 设置分段周边距
          func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, insetForSectionAtIndex:section) -> UIEdgeInsets {
      
              // 上,左,下,右
              return UIEdgeInsetsMake(20, 20, 20, 20)
          }
    • 分段头尾 设置

          // 设置分段头大小
          func collectionView(collectionView: UICollectionView!, layut collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection:section) -> CGSize {
      
              /*
                  width 为水平滑动时的间距有效,height 为垂直滑动时的间距有效
              */
      
              return CGSizeMake(20, 30)
          }
      
          // 设置分段尾大小
          func collectionView(collectionView: UICollectionView!, layut collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection:section) -> CGSize {
      
              /*
                  width 为水平滑动时的间距有效,height 为垂直滑动时的间距有效
              */
      
              return CGSizeMake(20, 30)
          }
      
          // 设置分段头尾视图
          func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
      
              return myView
          }
    • 网格点击 设置

          // 网格点击
          func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
      
          }
      
          // 网格取消点击,点击另一个表格的时候触发
          func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
      
          }

9、Storyboard 中设置

  • 在 Storyboard 场景中设置

    • Collection View Controller

      CollectionView3

      Selection...
      Clear on Appearance
    • Collection View

      CollectionView4

      Items设置不同类型的单元格数量
      Layout设置布局类型
      Scroll Direction设置网格滑动方向
      Accessories
      Section Header显示网格头
      Section Footer显示网格尾

      CollectionView5

      Cell Size网格单元的大小
      Header Size网格头的大小
      Footer Size网格尾的大小
      Min Spacing最小行列间距
      Section Insets网格边距
    • Collection Reusable View

      CollectionView6

  • 在 Storyboard 场景绑定的 Controller 中设置

    • 在 Storyboard 自带的 collectionViewCell 中没有 contentView,在使用 Cell 时显示的内容必须使用代码自定义,其它设置可以在系统自带的 Cell 上设置。
posted @ 2016-08-10 19:23 QianChia 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值