一.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. }
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. }
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 = ; 声音评论,高度是确定的
  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:] constrainedToSize:CGSizeMake(textW, MAXFLOAT)].height;
  8. commentH = + 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 = ;
  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 > ) {
  22. str = [NSString stringWithFormat:@"%ld",count];
  23. }
  24. [button setTitle:str forState:UIControlStateNormal];
  25. }
三.处理cell的外观细节
 
1.cell的选中样式很难看,我们怎么取消?
     1.1 设置cell的一个属性就可以了

  1. self.selectionStyle = UITableViewCellSelectionStyleNone;
     1.2 在哪里写代码?
          在初始化cell方法里面写          
  1. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
2.我们想把分割线设置的宽一点,怎么设置?
     首先,我们要先取消系统的分割线
  1. 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 += ;
  5. frame.size.height -= ;
  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];
 
 

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

  1. 不等高cell的tableView界面搭建

    一.搭建界面 1.界面分析 分析界面的层次结构,分析界面应该用什么控件来搭建 2.界面层次结构 分析之后,我们可以把这个界面分为四个模块(topView middleView commentView ...

  2. iOS开发——UI进阶篇(三)自定义不等高cell,如何拿到cell的行高,自动计算cell高度,(有配图,无配图)微博案例

    一.纯代码自定义不等高cell 废话不多说,直接来看下面这个例子先来看下微博的最终效果 首先创建一个继承UITableViewController的控制器@interface ViewControll ...

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

    1.iOS8之后利用storyBoard或者xib自定义不等高cell: 对比自定义等高cell,需要几个额外的步骤(iOS8开始才支持) 添加子控件和contentView(cell的content ...

  4. 不等高cell的搭建(一)

    一.界面搭建   1.确定开发模式      如果界面是固定的,可以用xib      界面的一些内容不固定,就用纯代码      cell用什么方式去开发(我们采用纯代码和xib结合的方式)   2 ...

  5. 纯代码自定义不等高cell

    数据模型.plist解析这里就不过多赘述. 错误思路之一: 通过在heightForRowAtIndexPath:方法中调用cellForRowAtIndexPath:拿到cell,再拿到cell的子 ...

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

    课题一:如何计算Cell高度 方案一:直接法(面向对象) 直接法,就是把数据布局到Cell上,然后拿到Cell最底部控件的MaxY值. 第一步:创建Cell并正确设置约束,使文字区域高度能够根据文字内 ...

  7. 处理不等高TableViewCell

    课题一:如何计算Cell高度 方案一:直接法(面向对象) 想知道妹纸爱你有多深?直接去问妹纸本人吧! 嗯!Cell也是一样的,想知道cell到底有多高?直接问Cell本人就好了.直接法,就是把数据布局 ...

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

    不等高的cell 给模型增加frame数据 所有子控件的frame cell的高度 @interface XMGStatus : NSObject /**** 文字\图片数据 ****/ // ... ...

  9. iOS开发——UI进阶篇(二)自定义等高cell,xib自定义等高的cell,Autolayout布局子控件,团购案例

    一.纯代码自定义等高cell 首先创建一个继承UITableViewCell的类@interface XMGTgCell : UITableViewCell在该类中依次做一下操作1.添加子控件 - ( ...

随机推荐

  1. notepad++ gvim editplus 三款选择试用

    notepad++开源  试用还不错  但默认不会识别语法高亮  要自己设置  比较烦 gvim 在XP下竟然无法返回命令行  百般折腾无奈放弃 editplus 自带资源栏  选择器  文件查找功能 ...

  2. MVC设计模式

    随着Web应用的商业逻辑包含逐渐复杂的公式分析计算.决策支持等,使客户机越 来越不堪重负,因此将系统的商业分离出来.单独形成一部分,这样三层结构产生了. 其中‘层’是逻辑上的划分. 三层体系结构是将整 ...

  3. 127 2016 int

    Type Storage Minimum Value Maximum Value   (Bytes) (Signed/Unsigned) (Signed/Unsigned) TINYINT 1 -12 ...

  4. var wi = 0; wi < arr.length; wi++

    思维 <?php$w = 123;$wb = $w;$w = 456;echo $wb;?><script type="text/javascript">  ...

  5. php://input,$_POST,$HTTP_RAW_POST_DATA区别

    我们先来看两个demo 例子:php://input 代码如下   post.php 代码如下   例子:$_post 代码如下   welcome.php 代码如下   再来看$GLOBALS [& ...

  6. 坑人的七牛CDN

    最近七牛CDN不知道咋啦的,一下子就不行了,提示错误信息如下 "upload image source key fail: unexpected EOF" 找客服提交工单都没有解决 ...

  7. SQL查询中关于索引使用的笔记

    建表KeyLevelStat (无主键),2个索引: CREATE TABLE KeyLevelStat( [Date] [int] NOT NULL, [Num] [varchar](8), [R0 ...

  8. 总结下遇到的C#新语法

    1.属性的private set读写器 public int x { get; private set; } 是另一种简写, set前面的private声明是告诉编译器属性X是只读(read-only ...

  9. ArcGIS API for Silverlight 当DataGrid选中项时,地图聚焦弹出窗口,并可以播放音频文件

    原文:ArcGIS API for Silverlight 当DataGrid选中项时,地图聚焦弹出窗口,并可以播放音频文件 先看效果图,然后上代码: <UserControl x:Class= ...

  10. JS给swf传参数

    不仅可以用flashvars ="name=12&age=23" 还可以在指定swf地址时传参数src="test.swf?name=12&age=23& ...