一.界面搭建
 
1.确定开发模式
     如果界面是固定的,可以用xib
     界面的一些内容不固定,就用纯代码
     cell用什么方式去开发(我们采用纯代码和xib结合的方式)
 
2.划分层次结构
     2.1 怎么划分?
          按照功能划分
          按照隐藏效果:在某些条件下,一些控件要一起隐藏,就可以放在同一模块中(前提是这些控件集中在一起) 
 
    2.2 分析界面发现cell的middleView和commentView不确定要不要显示
          所以,cell采用纯代码方法搭建
 
3.自定义cell
     3.1在创建cell的时候,就把所有可能显示的模块全部添加到cell上
          把所有可能出现的模块(控件)全部添加到cell里面,然后根据需求再决定某些模块(控件)是显示还是隐藏
 
     3.2根据服务器数据,决定某些模块是否隐藏
 
     3.3在哪里创建cell?
          采用注册的方法,底层会自动调用initWithStyle方法来创建cell
 
4.一个模块一个模块去搭建
     4.1把cell分解为四个模块,如上图
 
     4.2先把一个模块所有的内容(搭建界面)和业务逻辑处理完,在去处理下一个模块
 
     4.3模块的处理方式:先搭建界面,再处理界面业务逻辑
 
     4.4优点:业务逻辑清晰,不容易混淆
 
二.topView模块开发
 
1.xib搭建界面
 
     1.1分析界面有哪些控件来搭建
 
     1.2自定义uiview并创建xib,描述好界面后,把界面添加到cell里面
    
 
2.请求数据
     2.1 查看接口文档,使用afn发送网络请求
 
     2.2网络请求成功时,把数据转换成模型
 
     2.3在模型中定义属性(先自定义模型)
          查看界面需要使用哪些数据,就找到定义数据的属性定义到模型中
 
     2.3自定义视图模型,视图模型包含模型(就是在视图模型中定义一个模型的属性)
 
     2.4遍历模型,全部转换为视图模型
          创建视图模型对象
          用视图模型的模型属性来接收模型
          把视图模型保存到数组中
 
3.在视图模型中计算cell子控件的frame和高度
 
      3.1什么时候计算的
           在模型转视图模型的时候计算的
 
      3.2在哪里计算的?
           重写视图模型的模型属性的set方法,在方法里面计算cell的frame和高度,并定义属性保存起来
          因为,在模型转视图模型的时候,会把模型传给视图模型的模型属性,底层会触发视图模型的模型属性set方法,这个时候就去计算了
 
     3.3 cell的高度计算
          cell的高度就是Y轴方向最后一个控件的最大Y值
 
4.展示数据
 
     4.1怎么展示?
          在自定义cell里面定义视图模型属性
          创建cell之后,从数组中取出对应的视图模型,给cell的视图模型属性赋值(触发视图模型的set方法)
 
     4.2模型怎么接收数据的?
          在cell视图模型属性的set方法里面,设置cell的frame和cell的高度(直接从视图模型中去)
          在把视图模型的数据直接赋值给模型(触发模型的set方法)
          重写模型的set方法,然后给界面的UI元素赋值,这样就能在界面上看到数据了
 
5.注意点
     5.1 cell会循环利用,设置某项属性后,一定要记得还原
     5.2 运行会报一些莫名其妙的约束冲突
          是系统的自动拉伸约束有冲突,取消掉就可以了
 
三.middleView模块搭建
 
middleView模块的样式也分很多种
我们可以利用xib搭建不同样式的middleView,然后根据服务器数据决定显示哪种样式的middleView
注意:一定要把其它样式的middleView隐藏,还需要在其它地方还原,防止循环引用
根据需求我们可以把middleView分为四种样式:
 
1.textView样式
     也就是没有middleView,这种样式只要不显示middleView就可以了(把pictureView,videoView,voiceView隐藏)
     也不需要计算frame的高度了
 
2.pictureView样式
                 

2.1 分析界面有哪些控件组成, 界面怎么搭建?
          加载图片的时候:有一个gif图标,用ImageView来搭建,进度条可以放在一个view里面
                                     文字部分:如果是图片用ImageView,如果是文字,用label或button都行, 需要与用户交互就用button
          显示图片时:图片用ImageView搭建,下面的查看大图用button(有图片和文字,还有背景图片,还要与用户交互,只能用button)
          由于界面是固定的,可以采用xib来搭建
 
2.2 把pictureView添加到cel里面
 
2.3 请求数据
     
2.4 在视图模型中计算cell子控件的frame和高度
 
          2.4.1首先判断数据是什么类型的
               返回的类型是NSInther,可读性太差,可以定义枚举来替代,可读性就很好
 typedef enum : NSUInteger {
XTThemeItemTypeAll = ,
XTThemeItemTypeVideo = ,
XTThemeItemTypeVoice = ,
XTThemeItemTypePicture = ,
XTThemeItemTypeText =
} XTThemeItemType;
          注意:定义枚举的快捷键是:enum

 
          2.4.2 如果是text类型的就不需要计算了
 
          2.4.3 如果图片实际高度太高,我们就在模型里面定义一个属性来记录是否是大图
 
          2.4.4 给大图设置一个固定高度,不需要把大图全部展示出来了
      // middleView:一样计算方式
// 不是段子的时候,才需要计算中间View的Frame
if (item.type != XMGThemeItemTypeText) {
CGFloat middleW = textW;
CGFloat middleH = middleW / item.width * item.height;
if (middleH > XTScreenH) { // 大图
middleH = ;
item.is_bigPicture = YES;
}
CGFloat middleX = margin;
CGFloat middleY = _cellH;
_middleViewFrame = CGRectMake(middleX, middleY, middleW, middleH);
_cellH = CGRectGetMaxY(_middleViewFrame) + margin;
}
 
2.5 运行发现,如果是大图,图片就被压缩了,很难看,怎么解决?
           ImageView默认是图片填充的,就是把图片拉伸或压缩成整个ImageView的大小
           设置ImageView的内容模式,不让它压缩 UIViewContentModeTop
     
2.6 设置内容模式,发现虽然图片不被压缩,但是图片不能填充ImageView(两边是空的) 怎么解决?
          UIViewContentModeTop默认是图片上面显示到ImageView的顶部,但是不会进行拉伸或压缩
          我们需要先对图片进行拉伸或压缩处理,然后再设置 UIViewContentModeTop 就可以了
     
2.7 怎么对图片进行拉伸或压缩处理?
          可以用绘图,生成一张新的拉伸或压缩好的图片
     
2.8 怎么绘图?
          2.8.1 开启图形上下文
          2.8.2 绘制图片
          2.8.3 获取新的图片
          2.8.4 关闭图形上下文
     
2.9 对图片处理进行性能优化
     2.9.1 每次设置图片,都要进行绘图,有可能重复绘图,性能不好,怎么优化?
          把处理好的图片缓存到磁盘(沙盒)里面,下次再设置这张图片时,直接从磁盘取
 
     2.9.2 怎么对图片缓存处理?
          自己写方法太麻烦, SDImageCache.h内部有方法缓存图片,直接调用它的方法来进行缓存

   [[SDImageCache sharedImageCache] storeImage:image forKey:item.image0];
注意:要到入头文件: #import <SDImageCache.h>
     2.9.3 怎么从磁盘中去图片?
          同样也是调用SDImageCache.h方法来取
        UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.image0];

注意:key值就是图片的url

 
2.10 刚开始加载图片时,进度条怎么设置?
 
     2.10.1 需要设置一个功能模块的时候,我们要先去找有没有做该功能模块的框架,有就直接拿来用
 
     2.10.2 没有的话,就找一个功能差不多的模块来修改一下
 
     2.10.3 怎么去查找一个框架?
          

 
            - (void)awakeFromNib
{
_progressView.progressLabel.textColor = [UIColor whiteColor];
_progressView.progressTintColor = [UIColor whiteColor];
_progressView.roundedCorners = ; _progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",0.0 * ];
_progressView.progress = ;
} - (void)setItem:(XMGThemeItem *)item
{
_item = item; // 设置图片
UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.image0];
if (image) { 如果有图片直接设置,并把进度设为100%
_imageView.image = image;
_progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",1.0 * ];
_progressView.progress = ;
} else { 如果没有图片,就先把进度设置为0 ,再去下载图片
_progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",0.0 * ];
_progressView.progress = ;
// 下载网络图片
[_imageView sd_setImageWithURL:[NSURL URLWithString:item.image0] placeholderImage:nil options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {
进度就为已下载的文件大小 / 总文件大小
CGFloat progress = 1.0 * receivedSize / expectedSize;
运行发现,进度有时候为-,打印发现总文件大小该开始为- 当为- 的时候就返回
注意:该block会频换调用,所以 returen一次没关系
if (expectedSize < ) return ;
_progressView.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",progress * ];
_progressView.progress = progress; } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { if (!item.is_bigPicture) return ; // 生成一个新拉伸好图片
CGFloat w = XMGScreenW - ;
CGFloat h = w / item.width * item.height; // 开启图形上下文
UIGraphicsBeginImageContextWithOptions(CGSizeMake(w, h), NO, );
// 绘图
[image drawInRect:CGRectMake(, , w, h)];
// 获取上下文图片
image = UIGraphicsGetImageFromCurrentImageContext();
// 保存图片到沙盒
[[SDImageCache sharedImageCache] storeImage:image forKey:item.image0];
// 关闭上下文
UIGraphicsEndImageContext(); _imageView.image = image;
}];
}
根据服务器数据,决定gif图片是否显示
_gifView.hidden = !item.is_gif;
根据自己判断保存的属性,来决定显示大图按钮是否显示
_seeBigButton.hidden = !item.is_bigPicture; if (item.is_bigPicture) {
_imageView.contentMode = UIViewContentModeTop;
_imageView.clipsToBounds = YES;
} else {
_imageView.contentMode = UIViewContentModeScaleToFill;
_imageView.clipsToBounds = NO;
}
}
3.videoView样式  和  voiceView样式
 

3.1 由于这两个模块基本相同,处理方法也差不多
     注意:把搭建好的xib的view拷贝到另一个xib里面的时候,会把对应的连线也拷过去,一定要先删除这些连线,再继续使用
     

 
3.2 根据类型,只需要设置中间按钮的图片就可以了
     
3.3 xib搭建界面,并把界面添加到cell里面
    
3.4 请求数据
 
3.5 在视图模型中计算cell子控件的frame和高度
 
3.6 展示数据
 
     3.6.1 在videoView或voiceView的模型里设置数据的时候,要对数据进行处理
 
     3.6.2 为什么要处理?
          服务器返回的时间数据是以秒为单位的,需求以  00:00  来显示
 
     3.6.3 怎么处理?

     NSInteger minute = item.voicetime / ;
NSInteger second = item.voicetime % ;
self.timeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld",minute,second];
 
4 在cell模型属性的set方法里面统一设置middleView各个模块的frame的是否隐藏
 
     // middleView
if (vm.item.type == XMGThemeItemTypePicture) { // 图片
_pictureView.hidden = NO;
_videoView.hidden = YES;
_voiceView.hidden = YES; _pictureView.item = vm.item;
_pictureView.frame = vm.middleViewFrame; } else if (vm.item.type == XMGThemeItemTypeVideo) { // 视频
_pictureView.hidden = YES;
_videoView.hidden = NO;
_voiceView.hidden = YES; _videoView.item = vm.item;
_videoView.frame = vm.middleViewFrame;
} else if (vm.item.type == XMGThemeItemTypeVoice) { // 音频
_pictureView.hidden = YES;
_videoView.hidden = YES;
_voiceView.hidden = NO; _voiceView.item = vm.item;
_voiceView.frame = vm.middleViewFrame; } else {
_voiceView.hidden = YES;
_pictureView.hidden = YES;
_videoView.hidden = YES;
}
 
 

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

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

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

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

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

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

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

  4. 不等高cell搭建(二)

      一.commentView模块搭建 commentView样式分为两种     1.xib搭建界面   1.1 因为评论的样式大体上一样,我们可以用同一个xib来处理   1.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

    Storyboard_不等高 对比自定义等高cell,需要几个额外的步骤(iOS8开始才支持) 添加子控件和contentView之间的间距约束 设置tableViewCell的真实行高和估算行高 / ...

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

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

随机推荐

  1. .gitignore 配置

    .gitignore 配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为我们的版本管理带来很大的便利,以下是个人对于配置 .gitignore 的一些心得. 1.配置语法: 以斜杠“/”开头 ...

  2. X5学习笔记—给单元格添加颜色

    设置grid某一个单元格的颜色 可以用dhtmlxgrid的原生态方法 setCellTextStyle (row_id, ind, styleString) 参数: rowid:行id cellin ...

  3. JMX初体验

    这些天在看<How Tomcat Works>这本书.里面讲到了JMX的内容.对我来说是个新知识点. JMX--Java Management Extensions,即Java管理扩展,是 ...

  4. alibaba的FastJson(高性能JSON开发包)

    这是关于FastJson的一个使用Demo,在Java环境下验证的 class User{ private int id; private String name; public int getId( ...

  5. Android笔记:百度地图与高德地图坐标转换问题

    安卓项目使用了百度地图的定位SDK,web端使用的也是百度地图, 后来发现界面显示百度地图不如高德效果好,web改用高德地图,原本的百度地图坐标是可以直接使用的,由于高德和百度地图的坐标系不一致 要如 ...

  6. OC的内存管理

    摘自:http://blog.csdn.net/hahahacff/article/details/39839571 OC内存管理 一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有 ...

  7. JS控制flash的播放

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...

  8. iOS NSDate计算时间间隔

    //获取开始时间 NSDate* tmpStartData = [NSDate date]; /*( 执行代码段 )*/ ; i<; i++) { DLog(@"%d",i) ...

  9. Oracle中 根据 file# 和 block# 找到对象

    我们在10046生产的trace 文件里经常看到下面的信息. 表示系统在等待散列读取某个文件号的某个块开始的8个块. WAIT #6: nam='db file scattered read' ela ...

  10. JavaScript: JavaScript的简介和入门代码演示

    1.Javascript的发展历史介绍: javascript是指的实在网页上编写的编程语言,其主要是控制器html的动态显示效果.HTMl能带来的只是一些基本的页面的风格,而要展示的漂亮使用CSS, ...