自定义UICollectionViewCell 以及碰到的问题

自定义UICollectionViewCell 以及碰到的问题
原创 2016年09月12日 16:37:50 标签:UICollectionView /自定义UIControllViewCel /ios 10024
前言:

今天没事自己写了个UICollectionView也就是九宫格的demo ,遇到几个小问题,虽然都很快解决了,但是这里还是把它记录下来,以后方便查阅。
(UICollectionView 一下用九宫格代称)废话不多说了,直接开始。微笑
创建一个UICollectionView

首先,创建一个UICollectionView ,需要设置的几个代理 UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout。九宫格 跟UITableView类似,这里只是实现最简单的代理方法。
[objc] view plain copy

  • (UICollectionView *)collectionView
    {
    if (_collectionView == nil) {

      UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];  
    
      _collectionView = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:flowLayout];  
      _collectionView.delegate = self;  
      _collectionView.dataSource = self;  
      [_collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:CellIdentifier];  
        
      _collectionView.backgroundColor = [UIColor grayColor];  
    

    }

    return _collectionView;
    }

其中_collectionView 是我创建的九宫格,CollectionViewCell 是我创建的自定义Cell,这个下面再讲。
上面我就碰到了了一个小问题,其实也是我自己不细心的原因,但是也是容易出错的地方:
[objc] view plain copy
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];

_collectionView = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:flowLayout];
上面的UICollectionViewFlowLayout ,这个类是九宫格用来实现自动布局的,注意千万不要写错,我就因为写错,写成了
UICollectionViewLayout (这个类我是直接点击去九宫格的初始化方法里面看到的)导致了九宫格显示不出来,其他地方也没有错,
调了好几遍,最后终于发现是这个类写错了,UICollectionViewFlowLayout 是UICollectionViewLayout 的子类。
好了,一个问题过去了。
准备UICollectionView 的数据

在实现九宫格的代理方法之前,先展示一下 需要的数据
[objc] view plain copy
@property (nonatomic, copy) NSMutableArray *dataSourceArray;
//宏是完全替换

define CellWidthSpace 20

define CellWidth (kScreenWidth - (5 * CellWidthSpace))/4

define CellLineSpace 10

self.dataSourceArray = [NSMutableArray arrayWithArray:@[@"image1.png",@"image2.png",@"image3.png",<span style="font-family: Arial, Helvetica, sans-serif;">@"image4.png",@"image5.png",@"image4.png",@"image3.png",@"image2.png",@"image1.png"]];</span>
dataSourceArray 是九宫格的数据,CellWidthSpace 是每行Cell之间的间距,CellLineSpace 是每列Cell之间的间距,这个
都是自己定义的。 kScreenWidth 是整个屏幕的宽度,重点是CellWidth, 我要显示4列的九宫格,间距需要5个,所以就是 屏宽度
减去5个空隙 后再除以4.就得到了每个Cell的 的宽度。
实现UICollectionView的代理

[objc] view plain copy

pragma mark UICollectionViewDelegateFlowLayout

//设置每个Cell 的宽高

  • (CGSize)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
    {
    return CGSizeMake(CellWidth, CellWidth);<span style="white-space:pre"> </span>
    }
    //设置Cell 之间的间距 (上,左,下,右)
  • (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
    {
    return UIEdgeInsetsMake(CellLineSpace, CellWidthSpace, CellLineSpace, CellWidthSpace);
    }

pragma mark UICollectionViewDataSource

//设置九宫格Cell 的个数

  • (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
    return self.dataSourceArray.count;
    }
    //设置Cell

  • (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.imageName = self.dataSourceArray[indexPath.row];
    cell.backgroundColor = [UIColor whiteColor];

    return cell;
    }

pragma mark UICollectionViewDelegate

//设置点击 Cell的点击事件

  • (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    {
    [collectionView deselectItemAtIndexPath:indexPath animated:YES];//取消选中

    [self alertView:[NSString stringWithFormat:@"点击的是%ld",indexPath.row]];
    }
    //这个不是必须的方法 是Cell 将要显示

  • (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
    {
    cell.layer.transform = CATransform3DMakeScale(0.3, 0.3, 1);//缩放比例
    [UIView animateWithDuration:0.8 animations:^{
    cell.layer.transform = CATransform3DMakeScale(1, 1, 1);//还原为1
    }];<span style="white-space:pre"> </span> <span style="font-family: Arial, Helvetica, sans-serif;">}</span>
    [objc] view plain copy

pragma mark UIAlertView

  • (void)alertView:(NSString *)message
    {
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil nil];

    [alert show];
    }
    上面就是九宫格的代理方法(没有列全,只是简单实现了UICollectionView),上面的方法 看注释。
    自定义UICollectionViewCell

重点是设置Cell的方法,我是使用了自定义Cell,这里就会显示出UICollectionView 与 UITableview 的不同.
首先,UICollectionView 与UITableView 都有类似的
[objc] view plain copy
[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
这个是 Cell 的重用机制。UITableView 需要判断Cell是否 为空
[objc] view plain copy
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
如果cell =nil 里面就可以使用 自定义 UITableViewCell 这里不再说了,但是UICollectionView 不需要判断Cell 是否为nil,可以使用系统
的UICollectionViewCell 也可以使用自定义的UICollectionViewCell,我们一般用的就是自定义的Cell .
[objc] view plain copy

  • (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.imageName = self.dataSourceArray[indexPath.row];
    cell.backgroundColor = [UIColor whiteColor];

    return cell;
    }
    CollectionViewCell 就是我自定义的Cell ,imageName 是自定义Cell 里面添加的图片的名字。
    我们先来看一下自定义UICollectionViewCell 的文件,我实现的Cell 很简单就是添加了一个图片(这个自定义Cell 可以根据需要
    自行设置),
    [objc] view plain copy
    .h 文件

import <UIKit/UIKit.h>

@interface CollectionViewCell : UICollectionViewCell

@property (nonatomic, copy) NSString *imageName;

@end

.m 文件

import "CollectionViewCell.h"

@interface CollectionViewCell ()
@property (nonatomic, strong) UIImageView *imageView;

@end

@implementation CollectionViewCell

  • (instancetype)initWithFrame:(CGRect)frame
    {
    self = [super initWithFrame:frame];
    if (self) {
    }
    return self;
    }

  • (void)setImageName:(NSString *)imageName
    {
    //注意cell里面的控件 使用的位置 是相对于cell 的位置的 所以使用bounds
    _imageName = imageName;
    _imageView = [[UIImageView alloc]initWithFrame:self.bounds];
    _imageView.image = [UIImage imageNamed:imageName];
    [self addSubview:_imageView];
    }

@end

这里返回cell 的方法好像只能写
[objc] view plain copy

  • (instancetype)initWithFrame:(CGRect)frame
    我使用
    [objc] view plain copy

  • (instancetype)init
    {
    self = [super init];
    if (self) {

    }
    return self;
    }
    但是没有执行,好了。我们知道使用
    [objc] view plain copy

  • (instancetype)initWithFrame:(CGRect)frame
    去初始化一个自定义的Cell 。
    自定义UICollectionViewCell 注意

这里我又连续碰到了2个问题,当然我上面粘贴出来出来的都是正确的。先说说第一个问题,我是在
[objc] view plain copy

  • (instancetype)initWithFrame:(CGRect)frame
    {
    self = [super initWithFrame:frame];
    if (self) {
    self.imageView = [[UIImageView alloc]initWithFrame:self.bounds];
    self.imageView.image = [UIImage imageNamed:self.imageName];
    [self addSubview:_imageView];
    }
    return self;
    }
    这里面根据我传递过来的图片名字设置图片的,但是图片并没有显示出来。不知道你注意到了这个没有
    [objc] view plain copy

  • (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.imageName = self.dataSourceArray[indexPath.row];
    cell.backgroundColor = [UIColor whiteColor];

    return cell;
    }
    这个自定义UICollectionViewCell 是直接使用重用机制,调用系统的Cell 实例方法,但是我们设置自定义Cell 的图片信息,是在调用
    过系统的重用的实例方法 ,之后设置的。因为我们没有办法向自定义UITableViewCell 方法一样,实现我们自定义的实例方法。这就
    导致了系统在调用我们 自定义UICollectionViewCell 的时候里面的imageName 字符串还是nil ,所以图片显示不出来。这里我使用了
    重写setter方法,当然重写setter的时候可以传递过来一个模型的数据,来设置Cell 里面的显示的数据。
    [objc] view plain copy

  • (void)setImageName:(NSString *)imageName
    {
    //注意cell里面的控件 使用的位置 是相对于cell 的位置的 所以使用bounds
    _imageName = imageName;
    _imageView = [[UIImageView alloc]initWithFrame:self.bounds];
    _imageView.image = [UIImage imageNamed:imageName];
    [self addSubview:_imageView];
    }
    当我去设置 自定义Cell 里面的属性 iamgeName 的时候再去 添加图片。这样图片就能显示出来了。
    最后一个问题,我在重写setter方法的时候,设置cell的UIImageView frame的时候 ,出现的。显示为UIImageView 的图片位置
    不正确,能显示出来的只有2列,当我点击cell 提示的弹窗,提示信息跟我点击的cell图片不对应,最开始我以为是cell 的间距问题,
    调了两次,发现还是调整不大。当我设置Cell 的背景颜色 为一个明显的突出颜色的时候,就看出来问题的原因了。cell 的位置是正确
    的,错误的是cell的UIImageView 的位置。
    问题出现前:
    [objc] view plain copy
    _imageView = [[UIImageView alloc]initWithFrame:self.frame];
    问题解决:
    [objc] view plain copy
    _imageView = [[UIImageView alloc]initWithFrame:self.bounds];

问题的原因是,我设置UIImageView 的位置是 self.frame 这个位置是相对于整个UICollectionView 的,再添加自定义Cell 上面的时候,就不对了,那个位置是cell相对于父视图 UICollectionView的,添加到Cell 上面的,UIImageView 的父视图是Cell 而不是UICollectionView,所以设置图片视图UIImageView 的位置的时候应该用相对于Cell 位置的self.bounds .

以上,就是我在实现UICollectionView 的时候碰到的小问题,以及自定义UICollectionViewCell 。啦啦啦啦得意

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容