纯代码写CollectionViewCell的复用问题

需求:

需要的Button 的个数不一定 Button上显示的字符串的长度不一定,Button上显示的字符串和Button的个数全部从服务器下发 ,当Button的个数在屏幕上展示不下的时候要可以左右滑动 以展示更多的Button

方案:

综合以上因素 我选择利用CollectionView实现此功能.

其中遇到几个问题:

首先说明: cell中有一个Label 属性

- (UILabel*)textLabel{

if(!_textLabel) {

_textLabel= [[UILabelalloc]initWithFrame:self.contentView.frame];

_textLabel.layer.borderWidth=1;

_textLabel.layer.borderColor= [UIColorlightGrayColor].CGColor;

_textLabel.font= [UIFontsystemFontOfSize:13];

_textLabel.textAlignment=NSTextAlignmentCenter;

_textLabel.textColor= [UIColorblackColor];

[self.contentViewaddSubview:_textLabel];

}

_textLabel.frame=CGRectMake(CGRectGetMinX(self.contentView.frame),CGRectGetMinY(self.contentView.frame),self.frame.size.width,self.frame.size.height);

return_textLabel;

}

问题 一 :因为选中cell时 cell的字和边框要变成红色 ,当再点击其他Item时此item要变为原来的样子

这个功能主要在collectionView的两个代理方法中实现

- (void)collectionView:(UICollectionView*)collectionView didSelectItemAtIndexPath:(NSIndexPath*)indexPath;

- (void)collectionView:(UICollectionView*)collectionView didDeselectItemAtIndexPath:(NSIndexPath*)indexPath;;

具体实现如下:

/**

*当点击item时会调用此方法在此方法中把点击的item的textLabel属性的字体颜色和边框改变颜色

*

*/

- (void)collectionView:(UICollectionView*)collectionView didSelectItemAtIndexPath:(NSIndexPath*)indexPath{

JWCCollectionViewCell*cell = (JWCCollectionViewCell*)[collectionViewcellForItemAtIndexPath:indexPath];

cell.textLabel.textColor= [UIColorredColor];

cell.textLabel.layer.borderColor= [UIColorredColor].CGColor;

}

/**

*当点击其他cell时调用此方法比如点击第一个cell的时候调用上面的方法,当点击第二个的时候先调用此方法,然后再调用上面的方法

在此方法中获取第一次点击的cell即

JWCCollectionViewCell *cell = (JWCCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];

把此cell的textLabel属性变回原来的样子然后系统会调用上面的代理方法把点击的第二个cell的textLabel属性的字体颜色和边框改变颜色

这样就实现了点击此cell改变颜色再点击其他的cell是时上一个点击的cell恢复到原来的样子

*

*/

- (void)collectionView:(UICollectionView*)collectionView didDeselectItemAtIndexPath:(NSIndexPath*)indexPath{

JWCCollectionViewCell*cell = (JWCCollectionViewCell*)[collectionViewcellForItemAtIndexPath:indexPath];

cell.textLabel.textColor= [UIColorblackColor];

cell.textLabel.layer.borderColor= [UIColorlightGrayColor].CGColor;

}

问题二:

假如cell的个数太多的话肯定会发生复用的问题:

比如数:屏幕的宽度只能显示3个cell但是现在有四个需要显示,那么当点击第一个cell向左滑动时会显示第四个 这个时候第四个item就是从复用队列中取出一个cell ,那么这个cell可能还保留这上一个的属性 比如说字体是红色的 其宽度可能会很大,不适合当前的string的宽度 ,左右滑动的时候cell 之间的间隔也会发生错乱 这绝不是想要的结果 。出现这个原因主要是cell的复用产生的。

解决方法:

在cell复用之前把cell恢复到初始化状态,那么这就要重写- (void)prepareForReuse方法

具体做法如下:

- (void)prepareForReuse{

[superprepareForReuse];

_textLabel.frame=self.contentView.frame;

_textLabel.layer.borderWidth=1;

_textLabel.textColor= [UIColorblackColor];

_textLabel.layer.borderColor= [UIColorlightGrayColor].CGColor;

}

这样就解决了颜色问题

注意:prepareForReuse这个方法是CollectionViewCell的方法

但是错乱问题仍然没有解决:这主要是因为在定义_textLabel 时它的frame设置问题 应该在添加一句

_textLabel.frame=CGRectMake(CGRectGetMinX(self.contentView.frame),CGRectGetMinY(self.contentView.frame),self.frame.size.width,self.frame.size.height);

具体是这样的

----------------------------------------------------------------------------------------------

- (UILabel*)textLabel{

if(!_textLabel) {

_textLabel= [[UILabelalloc]initWithFrame:self.contentView.frame];

_textLabel.layer.borderWidth=1;

_textLabel.layer.borderColor= [UIColorlightGrayColor].CGColor;

_textLabel.font= [UIFontsystemFontOfSize:13];

_textLabel.textAlignment=NSTextAlignmentCenter;

_textLabel.textColor= [UIColorblackColor];

[self.contentViewaddSubview:_textLabel];

}

_textLabel.frame=CGRectMake(CGRectGetMinX(self.contentView.frame),CGRectGetMinY(self.contentView.frame),self.frame.size.width,self.frame.size.height);

return_textLabel;

}

----------------------------------------------------------------------------------------------

问题三:

比如说 当点击第一个cell 后 向左滑动让第一个消失在界面中,当再滑出界面时你会发现它的选中状态消失了,而你并没有选中其他的cell ,这是为什么???因为上一问题的解决方法导致了这一步。那么该怎么样解决才能不至于解决上面的问题引出下面的问题呢??方法如下:

1,  定义一个全局变量:

@property(nonatomic,assign)NSIntegerselectIndex;

2 这个先给它赋一个永远也不可能达到的值

self.selectIndex=MAXFLOAT;至于为什么赋这么大下面说

3,在- (void)collectionView:(UICollectionView*)collectionView didSelectItemAtIndexPath:(NSIndexPath*)indexPath;这个代理方法中把indexPath.row值赋值给self.selectIndex如下

self.selectIndex= indexPath.row; 这就记住了所选择的item的位置

4,在- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath;这个方法中可能会从复用队列中去处cell 产生复用 但在复用之前会调用- (void)prepareForReuse方法 又会恢复原样使选中状态消失,这个时候要判断一下,判断这个方法中的 indexPath.row 是否等于self.selectIndex 如果等于 使其变为选中的状态,具体代码如下:

- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath {

JWCCollectionViewCell*cell = [collectionViewdequeueReusableCellWithReuseIdentifier:@"cellID"forIndexPath:indexPath ];

if(indexPath.row==_selectIndex) {

cell.textLabel.textColor= [UIColorredColor];

cell.textLabel.layer.borderColor= [UIColorredColor].CGColor;

}

cell.textLabel.text= [self.dataSourceArrobjectAtIndex:indexPath.item];

NSLog(@"%@",cell.textLabel.text);

returncell;

}

这样即使选中的cell 消失在界面中在出现的时候也不会改变选中状态。

为什么要把self.selectIndex=MAXFLOAT

如果不这样赋值  假如赋的值为0 那么每次打开时第一个cell就是选中状态,但是你并没有点击第一个。这主要是在cell生成的代理方法中的这一句代码引起的

if(indexPath.row==_selectIndex) {

cell.textLabel.textColor= [UIColorredColor];

cell.textLabel.layer.borderColor= [UIColorredColor].CGColor;

}

所以把self.selectIndex赋值为MAXFLOAT 这样就不会有当一启动APP的时候就有cell被选中的状态

问题四:

根据string的宽度不同来生成的cell的宽度也不同的功能是在

- (CGSize)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath*)indexPath;

实在这个方法中返回不通的CGSize 来改变每一个cell的宽度。

在此可以计算字符串的宽度:

具体的方法如下:

#pragma mark - UICollectionViewFlowLayoutDelegate

- (CGSize)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath*)indexPath{

NSString*str =  [self.dataSourceArrobjectAtIndex:indexPath.item];

CGRectrect = [selfgetStringRect:strwithFont:13];

returnCGSizeMake(rect.size.width,30);

}

/**

*计算字符串的宽度的方法

*/

- (CGRect)getStringRect:(NSString*)aString withFont :(CGFloat)font

{

CGRectrect;

if(aString){

CGRectrect = [aStringboundingRectWithSize:CGSizeMake(MAXFLOAT,30)options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeadingattributes:@{NSFontAttributeName: [UIFontsystemFontOfSize:font]}context:nil];

returnrect;

}

returnrect;

}

注意注意:!!!!

- (CGRect)getStringRect:(NSString*)aString withFont :(CGFloat)font 在这个方法中需要传入字体的大小。

这个大小一定要和 textLabel初始化时的字体大小一样 比如本例中在初始化的时候是13 那么在计算字符串的宽度的时候一定要是13 不然计算出的字符串的宽度比实际的要长 :会出现的问题是当左右滑动时会出现各个cell之间的间隔会出现改变 也许会两个cell会出现重叠!!

_textLabel.font= [UIFontsystemFontOfSize:13];

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

推荐阅读更多精彩内容