不等高cell搭建(二)

一.commentView模块搭建

commentView样式分为两种

1.xib搭建界面

1.1 因为评论的样式大体上一样,我们可以用同一个xib来处理

1.2 最热评论   用一个label来搭建

1.3 下面的内容不一样

1.3.1 文本样式的评论,下面也用一个label搭建就可以了

label约束设置为左右和上面固定间距,这样,高度会随着内容缩放,前提是设置label为0行

1.3.2 声音样式评论

声音样式的评论.高度是固定的

先添加一个view在文本评论的位置(根据数据再决定到时候哪种样式的评论显示,上面的部分是一样的)

再往view里面添加一个label 和 button 就行了

注意:button的图片和文字有间距   只需要设置内部子控件的内边距就行了

如果label下面对view有约束,button下面就不要对view设置约束了   会有冲突, 总之,设置其中一个,另一个就不要设置了

2.请求数据

2.1 在设置模型属性的时候,我们要对数据进行处理

2.2 从上图中可以看到,我们需要拿到username  首先要拿到top_cmt这个数组,然后再拿到 user字典

2.3 我们习惯都是面向模型开发,所以我们拿到 top_cmt 数组的第一个元素(字典)  转为模型

2.4 然后取出字典中的user字典,在转为另一个模型

2.5 那么我们就需要先自定义两个模型

2.6 我们最好在最外层模型中定义一个模型属性,来保存内层的一个模型(item0  也是就是评论模型)  为什么?

在取内层模型属性的时候,会因为层级太深,需要写很长一段代码

进行这样的优化后,取内层模型属性的时候,就方便很多

2.7 怎么把模型中的数组属性里面的字典转换为  模型中的一个属性

重写数组元素的set方法   只要拿到数组中的字典元素,给模型中的这个属性赋值

为了严谨,要判断数组是否为空

1 // 给模型的top_cmt属性赋值调用
2 - (void)setTop_cmt:(NSArray *)top_cmt
3 {
4     _top_cmt = top_cmt;
5     if (top_cmt.count) {
6         _commentItem = top_cmt.firstObject;
7     }
8 }
9  

3.怎么在外层模型里面,把模型中的数组属性中的字典(或字典属性)转成模型?

有两种方法来转

3.1第一种方法 ,自己手动利用MJ框架来转

3.2第二种方法,让MJ框架自动帮我们转,(前提是MJ框架知道模型中属性要转成哪种类型的模型)

3.3 MJ框架怎么自动帮我们转内层模型?

MJExtension:如果模型中有模型,MJExtension会自动帮你转换好

@property (nonatomic, strong) XTUserItem *user;

因为我们在定义这个字典的时候,就告诉MJ框架,要把字典转为哪种类型的模型

MJExtension:如果模型中有数组,数组中又是字典,MJExtension不会自动帮你转

MJExtension可以把数组中字典转模型 ,但是需要告诉他要把数组中的字典转为哪种类型的模型

3.4 怎么告诉MJ把数组中的字典转为哪种类型的模型

1 // key:哪个数组需要转换
2 + (NSDictionary *)mj_objectClassInArray
3 {
4     return @{@"top_cmt":@"XTCommentItem"};
5 }
6  

3.5 MJExtension底层实现

3.5.1 MJ底层是利用KVC对模型进行赋值的

遍历模型中的key, 然后去字典中查找对应的value对key赋值

3.5.2 利用kvc赋值,模型中可以没有字典中的某些key值, 但模型中的key 在字典中一定要有对应的value,否则会报错

MJ框架不存在这个问题,

kvc底层实现:       http://www.jianshu.com/p/45cbd324ea65

KVC是通过[item setValuesForKeysWithDictionary:dict]这个方法,将字典转为模型

setValuesForKeysWithDictionary:底层实现

便利字典当中的所有Key Value值.给对应的key,value赋值

[dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {

给对应的key,value赋值

setValuesForKeysWithDictionary:会调用setValue:forKeyPath:

[item setValue:obj forKeyPath:key];

}];

setValue:forKeyPath:的底层实现:

setValue: forKeyPath:

1.根据key值与当前的属性进行对比,先去看有没有与key值相同的set方法.如果有,就调用set方法.

2.如果没有,再去对比,有没有跟key值相同的成员属性,如果有,就直接进行赋值.

3.如果没有,再去对比,有没有跟key值相同的而且带有下划线的成员属性,如果有,就直接进行赋值.

4.如果还没有,会调用setValue:(id)value forUndefinedKey:

5.如果没有实现,直接报错.

3.5.3 kvc要求,在模型中定义的key值得数据类型  一定要跟字典中key对应的value的值的数据类型相同,否则会报错

3.5.4 MJ框架,能够把一些key值的数据类型自动转换为和字典中key对应的value的数据类型(前提是,这个两种数据类型能相互转换)

4.在视图模型中计算cell子控件的frame和高度

 1   if (item.commentItem) { // 先判断有没有最热评论,有评论才需要计算
 2         CGFloat commentH = 42;  声音评论,高度是确定的
 3         注意点:以后只要判断字符串有没有内容,用长度
 4         if (item.commentItem.content.length) { // 有内容,就是文本评论
 5             根据文字的高度来计算评论的高度
 6             NSString *totalStr = [NSString stringWithFormat:@"%@:%@",item.commentItem.user.username,item.commentItem.content];
 7             textH = [totalStr sizeWithFont:[UIFont systemFontOfSize:17] constrainedToSize:CGSizeMake(textW, MAXFLOAT)].height;
 8             commentH = 21 + textH;
 9         }
10         CGFloat commentW = textW;
11         CGFloat commentX = margin;
12         CGFloat commentY = _cellH;
13         _commentViewFrame = CGRectMake(commentX, commentY, commentW, commentH);
14         _cellH = CGRectGetMaxY(_commentViewFrame) + margin;
15     }

5.展示数据

可以根据top_cmt数组的元素个数来判断commentView是否显示  或者根据这个数组中的元素转换的模型是否存在判断

二.bottomView模块搭建

此界面搭建相对来说比较简单,就不做具体介绍了

1.xib搭建界面

2.请求数据

2.1 查看接口文档,使用afn发送网络请求

2.2网络请求成功时,把数据转换成模型

2.3在模型中定义属性(先自定义模型)

查看界面需要使用哪些数据,就找到定义数据的属性定义到模型中

2.3自定义视图模型,视图模型包含模型(就是在视图模型中定义一个模型的属性)

2.4遍历模型,全部转换为视图模型

创建视图模型对象

用视图模型的模型属性来接收模型

把视图模型保存到数组中

3.在视图模型中计算cell子控件的frame和高度

高度给一个固定值就行了,cell的高度就是Y轴方向最后一个控件的最大Y值

4.展示数据

4.1展示数据的方法都一样,这里主要是对数据进行一些处理

4.2当评论或赞的数字超过一万的时候要进行处理

4.2.1 超过一万,让总数除以一万,得到的数字保留一位小数,显示xx.x万

4.2.2 如果总数为0的话,显示在界面上,效果很差,我们要进行一些处理

如果数据为0, 我们就在界面显示占位文字

 1 处理数据原码
 2 - (void)setItem:(XTThemeItem *)item
 3 {
 4     [super setItem:item];
 5
 6     [self setButton:_dingView count:item.ding title:@"赞"];
 7     [self setButton:_caiView count:item.cai title:@"踩"];
 8     [self setButton:_shareView count:item.repost title:@"转发"];
 9     [self setButton:_commentView count:item.comment title:@"评论"];
10 }
11
12 - (void)setButton:(UIButton *)button count:(NSInteger)count title:(NSString *)title
13 {
14      如何抽取一个方法:先把要抽取成方法的源代码拷贝过来,缺什么补什么就行了,需要外界决定的东西,写成参数,让外界传递进来
15     CGFloat valueF = 0;
16     NSString *str = title;
17     if (count > 10000.0) {
18         valueF = count / 10000.0;
19         str = [NSString stringWithFormat:@"%.1f万",valueF];
20         str = [str stringByReplacingOccurrencesOfString:@".0" withString:@""];
21     } else if (count > 0) {
22         str = [NSString stringWithFormat:@"%ld",count];
23     }
24     [button setTitle:str forState:UIControlStateNormal];
25 }
26  

三.处理cell的外观细节

1.cell的选中样式很难看,我们怎么取消?

1.1 设置cell的一个属性就可以了

     self.selectionStyle = UITableViewCellSelectionStyleNone;

1.2 在哪里写代码?

在初始化cell方法里面写

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

2.我们想把分割线设置的宽一点,怎么设置?

首先,我们要先取消系统的分割线

 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

2.1自定义分割线

给cell的底部加一个uiview设置高度和颜色能达到分割线的效果

2.2 设置cell的frame,让cell的高度减少一个值,减少的部分就能看到背景色,只需要设置背景色就可以达到设置分割线的目的

注意:在这里减少的值,一定要在设置cell的高度的时候加上去,否则cell可能被压缩

1 设置frame源代码
2 - (void)setFrame:(CGRect)frame
3 {
4     frame.origin.y += 10;
5     frame.size.height -= 10;
6 注意:一定要调用super方法
7     [super setFrame:frame];
8 }

2.3 给cell设置背景图片

通过 backgroundView属性给cell设置背景图片,只需要给cell的 backgroundView设置UIImageView就可以了

设置完发现,背景图片边缘有些难看,很有可能是图片被拉伸了,我们要对图片进行处理

设置图片的可拉伸区域,然后再设置cell的背景图片

1 设置cell背景图片原码
2  UIImage *image = [UIImage imageNamed:@"mainCellBackground"];
3 处理图片:设置可拉伸区域
4 image = [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5];
5
6 self.backgroundView = [[UIImageView alloc] initWithImage:image];

时间: 2024-07-30 12:14:44

不等高cell搭建(二)的相关文章

不等高cell的tableView界面搭建

一.搭建界面 1.界面分析 分析界面的层次结构,分析界面应该用什么控件来搭建 2.界面层次结构 分析之后,我们可以把这个界面分为四个模块(topView middleView commentView bottomView) 这种复杂的界面,我们一般称为:不等高cell 3.界面搭建方式 分析发现,界面大部分是不能确定的(文字高度,有没有图片,评论) 所以我们采用纯代码的方法来搭建界面 但是复杂的界面我们划分过之后,有些小模块里面的内容是固定的 这些固定的小模块我们可以采用xib来搭建 4.有些模

自定义不等高cell—storyBoard或xib自定义不等高cell

1.iOS8之后利用storyBoard或者xib自定义不等高cell: 对比自定义等高cell,需要几个额外的步骤(iOS8开始才支持) 添加子控件和contentView(cell的contentView)之间的间距约束(需要代码控制约束) 设置tableViewCell的真实行高和估算行高 // 以下两行代码就被苹果成为self0sizing技术,可惜只能在iOS8及其之后应用 // 告诉tableView所有cell的真实高度是自动计算(根据设置的约束来计算) self.tableVie

不等高cell的搭建(一)

一.界面搭建 1.确定开发模式 如果界面是固定的,可以用xib 界面的一些内容不固定,就用纯代码 cell用什么方式去开发(我们采用纯代码和xib结合的方式) 2.划分层次结构 2.1 怎么划分? 按照功能划分 按照隐藏效果:在某些条件下,一些控件要一起隐藏,就可以放在同一模块中(前提是这些控件集中在一起) 2.2 分析界面发现cell的middleView和commentView不确定要不要显示 所以,cell采用纯代码方法搭建 3.自定义cell 3.1在创建cell的时候,就把所有可能显示

纯代码自定义不等高cell

数据模型.plist解析这里就不过多赘述. 错误思路之一: 通过在heightForRowAtIndexPath:方法中调用cellForRowAtIndexPath:拿到cell,再拿到cell的子控件的最大Y值的方法是不可取的.会出现死循环,因为cellForRowAtIndexPath:方法中会调用heightForRowAtIndexPath:方法.错误思路之二: 在layoutSubviews方法中,根据子控件的高度,计算cell的高度.先初始化一个变量为0为cell的高度,计算出来所

处理不等高TableViewCell

课题一:如何计算Cell高度 方案一:直接法(面向对象) 想知道妹纸爱你有多深?直接去问妹纸本人吧! 嗯!Cell也是一样的,想知道cell到底有多高?直接问Cell本人就好了.直接法,就是把数据布局到Cell上,然后拿到Cell最底部控件的MaxY值. 第一步:创建Cell并正确设置约束,使文字区域高度能够根据文字内容多少自动调整 第一步 - 添加好约束.gif 第二步:再给这个Cell添加点别的东东,就叫这个东东BottomCub了.为Cub添加好约束. 第二步 - 随便添加点什么.gif

iOSTableViewCell不等高的几种方法

方案一:直接法(面向对象) 直接法,就是把数据布局到Cell上,然后拿到Cell最底部控件的MaxY值. 第一步:创建Cell并正确设置约束,使文字区域高度能够根据文字内容多少自动调整 添加好约束 第二步:再给这个Cell添加点别的东东,就叫这个东东BottomCub了.为Cub添加好约束. 随便添加点什么 第三步:为这个Cell写一个返回Cell高度 - 也就是BottomCub最大Y值的方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

iOS之处理不等高TableViewCell的几种方法

课题一:如何计算Cell高度 方案一:直接法(面向对象) 直接法,就是把数据布局到Cell上,然后拿到Cell最底部控件的MaxY值. 第一步:创建Cell并正确设置约束,使文字区域高度能够根据文字内容多少自动调整 添加好约束 第二步:再给这个Cell添加点别的东东,就叫这个东东BottomCub了.为Cub添加好约束. 随便添加点什么 第三步:为这个Cell写一个返回Cell高度 - 也就是BottomCub最大Y值的方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

iOS-UI控件之UITableView(二)- 自定义不等高的cell

不等高的cell 给模型增加frame数据 所有子控件的frame cell的高度 @interface XMGStatus : NSObject /**** 文字\图片数据 ****/ // ..... /**** frame数据 ****/ /** 头像的frame */ @property (nonatomic, assign) CGRect iconFrame; // ..... /** cell的高度 */ @property (nonatomic, assign) CGFloat c

iOS-UI控件之UITableView(三)- 自定义不等高的cell

Storyboard_不等高 对比自定义等高cell,需要几个额外的步骤(iOS8开始才支持) 添加子控件和contentView之间的间距约束 设置tableViewCell的真实行高和估算行高 // 告诉tableView所有cell的真实高度是自动计算(根据设置的约束来计算) self.tableView.rowHeight = UITableViewAutomaticDimension; // 告诉tableView所有cell的估算高度 self.tableView.estimated