iOS边练边学--自定义非等高的cell
一、使用xib或者storyboard自定义非等高的cell实现方式差不多,这里简单介绍一下通过xib文件实现的方法
<1.1>创建一个继承自UITableViewCell的子类,比如ChaosWeiboCell
<1.2>在模型中增加一个cellHeight属性,用来存放对应的cell的高度
#import <UIKit/UIKit.h> // 这里修改成UIKit框架 @interface ChaosWeibo : NSObject // 模型类
/** 正文 */
@property(nonatomic,strong) NSString *text;
/** 头像 */
@property(nonatomic,strong) NSString *icon;
/** 配图 */
@property(nonatomic,strong) NSString *picture;
/** 用户名 */
@property(nonatomic,strong) NSString *name;
/** VIP */
@property(nonatomic,assign,getter=isVIP) BOOL vip;
// CGFloat在CG框架里面 NSString *在Foundation框架里面,UIKit框架包含了这两个框架
/** cell的高度 */
@property(nonatomic,assign) CGFloat cellHeight; // 提供一个将字典数据转换成模型数据的类方法
+ (instancetype)WeiboWithDict:(NSDictionary *)dict;
@end
<2>创建一个xib文件(文件名建议跟cell的类名一样),比如ChaosWeiboCell.xib
<2.1>拖拽一个UITableViewCell出来
<2.2>修改cell的class为ChaosWeiboCell
<2.3>设置cell的重用标识
<2.4>往cell中添加需要用到的子控件
<3>在控制器中
<3.1>利用registerNib...方法注册xib文件
<3.2>利用重用标识找到cell(如果没有注册xib文件,就需要手动去加载xib文件)
<3.3>给cell传递模型数据
<3.4>在控制器中实现tableView:estimatedHeightForRowAtIndexPath:方法,返回一个估计高度,比如200
// 给cell一个估计高度
// 这个方法的意义在于:没有这个方法,程序的执行顺序是1、heightForRowAtIndexPath:方法得到cell的高度(高度不准确,有几个就获得几个的cell高度,消耗内存)2、然后cellForRowAtIndexPath:方法根据不准确的高度创建cell
// 有了这个方法程序会根据这个大约的高度先去执行cellForRowAtIndexPath:方法,然后再执行heightForRowAtIndexPath:方法返回真正的cell高度
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 200;
}
@end
<3.5>在控制器中实现tableView:heightForRowAtIndexPath:方法,返回cell的真实高度(模型中的cellHeight属性)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
ChaosWeibo *weibo = self.weiboArray[indexPath.row];
return weibo.cellHeight;
}
<4>在ChaosWeiboCell中
<4.1>将xib中的子控件连线到类扩展中
<4.2>需要提供一个模型属性,重写set方法,在这个方法中设置模型属性到子控件上
并且在set方法中调用[self layoutIfNeed]方法强制布局,然后计算出模型的cellHeight属性值
- (void)setWeibo:(ChaosWeibo *)weibo
{
// 重写set方法不可少的代码
_weibo = weibo;
// 设置头像
self.headView.image = [UIImage imageNamed:weibo.icon];
// 设置昵称
self.nameLabel.text = weibo.name;
// 设置会员标志
if (weibo.isVIP) {
self.vipView.hidden = NO; // 重新将hidden属性设置为NO,因为cell是通过缓存池回收过来的,万一之前是hidden,这里没有这一句就不行了
self.vipView.image = [UIImage imageNamed:@"vip"];
self.nameLabel.textColor = [UIColor orangeColor];
} else{
self.vipView.hidden = YES;
self.nameLabel.textColor = [UIColor whiteColor];
}
// 设置正文内容
self.contentLabel.text = weibo.text;
if (weibo.picture) {
self.iconView.hidden = NO; // 同理
self.iconView.image = [UIImage imageNamed:weibo.picture];
} else {
self.iconView.hidden = YES;
}
// 将绑定好数据的cell进行强制布局
[self layoutIfNeeded]; // 计算cell的高度
if (self.iconView.hidden) { // 没有配图的情况
weibo.cellHeight = CGRectGetMaxY(self.contentLabel.frame) + 10;
} else { // 有配图的情况
weibo.cellHeight = CGRectGetMaxY(self.iconView.frame) + 10;
}
}
<4.3>也可以将创建获得cell的代码封装起来(比如cellWithTableView:方法)
<5>需要注意的一点就是label的宽度问题,由于layoutIfNeed方法的原因,系统有时候算出的高度会于实际不符。因为系统算的高度是根据文字宽度算的。
解决办法,通过调用一下方法:
// 这个方法是自定义控件从xib文件初始化完后调用的方法,通过这个方法解决多行label算的高度不准的情况
- (void)awakeFromNib
{
// 设置每一行label文字的最大宽度
// 保证算出来的label的高度 跟 显示出来的效果一样
self.contentLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
}

iOS边练边学--自定义非等高的cell的更多相关文章
- iOS边练边学--自定义等高的cell
一.storyboard自定义cell <1>创建一个继承自UITableViewCell的子类,比如ChaosDealCell <2>在storyboard中 <2.1 ...
- 自定义非等高 Cell
1.自定义非等高 Cell介绍 1.1 代码自定义(frame) 新建一个继承自 UITableViewCell 的类. 重写 initWithStyle:reuseIdentifier: 方法. 添 ...
- iOS边练边学--CALayer,非根层隐式动画,钟表练习
一.CALayer UIView之所以能显示在屏幕上,完全是因为他内部的一个图层 在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性 ...
- iOS边练边学--(Quartz2D)基本图形的绘制#附加自定义进度控件的练习
一.Quartz2D使用须知 Quartz2D的API是纯C语言的 Quartz2D的API来自于Core Graphics框架 二.<1>通过原始的方法(C语言)绘制简单图形--了解 & ...
- iOS边练边学--父子控制器之自定义控制器的切换
一.如图所示的界面,按钮One.Two.Three分别对应三个控制器的view,点击实现切换.个人感觉父子控制器的重点在于,控制器的view们之间建立了父子关系,控制器不建立的话,发生在view上面的 ...
- iOS边练边学--应用数据存储的常用方式(plist,Preference,NSKeyedArchiver)其中的三种
iOS应用数据存储的常用方式: XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3--这里暂且不讲 Core D ...
- iOS边练边学--多线程介绍、NSThread的简单实用、线程安全以及线程之间的通信
一.iOS中的多线程 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块) iOS中多线程的实现方案有以下几种 二.NSThread线程类的简单实用(直接上代码 ...
- iOS边练边学--文件压缩和解压缩的第三方框架SSZipArchive的简单使用
一.非cocoaPods方法,需要注意的是:直接将SSZipArchive拖入项目编译会报错. Undefined symbols for architecture x86_64: "_cr ...
- iOS边练边学--iOS中的XML数据解析
XML的解析方式 SAX 大小文件都可以 NSXMLParser DOM 最好是小文件 GDataXML NSXMLParser的用法 创建解析器来解析 // 创建XML解析器 NSXMLParser ...
随机推荐
- windows添加开机启动项
http://www.cnblogs.com/jokey/archive/2010/06/17/1759370.html添加开机启动项(通过注册表) 例子:增加QQ开机启动项 第一步:找到注册表的启动 ...
- 你的Android不好用,都是因为这几点原因
Android早已是全球最大.用户最多的移动操作系统,不过它离全球最好用还差得很远. 大家随手就能举出些曾经历过的糟心体验,如手机卡顿!电量不禁用!广告弹窗老是出现!不过很少有人会追根寻底的去问为何如 ...
- 使用VUE+iView+.Net Core上传图片
我们直接进入主题,使用VS2017开发工具 首先要创建一个WebApi项目,创建完之后,在wwwroot文件下,创建一个文件夹 名字可以随意起 我这里呢就叫做Upload了 ok ! 然后我们再创建 ...
- POSIX 消息队列 和 系列函数
一.在前面介绍了system v 消息队列的相关知识,现在来稍微看看posix 消息队列. posix消息队列的一个可能实现如下图: 其实消息队列就是一个可以让进程间交换数据的场所,而两个标准的消息队 ...
- System V 共享内存区
1.概述 系统调用mmap通过映射一个普通文件实现共享内存.System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文 ...
- Python rsplit() 方法
描述 Python rsplit() 方法通过指定分隔符对字符串进行分割并返回一个列表,默认分隔符为所有空字符,包括空格.换行(\n).制表符(\t)等.类似于 split() 方法,只不过是从字符串 ...
- HTML - SELECT默认选中
除了在option中定义属性selected = "selected",还可以 <select defaultValue='2'> <option value=& ...
- 在python中配置MySQL数据库
MySQL数据库(1) 尽管用文件形式将数据保存到磁盘,已经是一种不错的方式.但是,人们还是发明了更具有格式化特点,并且写入和读取更快速便捷的东西——数据库(如果阅读港台的资料,它们称之为“资料库”) ...
- 简单易懂的laravel事件,这个功能非常的有用(监听事件,订阅者模式)
先说一下在什么场景会使用这个事件功能. 事情大概是这样的,需求要在用户注册的时候发一些帮助邮件给用户(原本用户在注册之后已经有发别的邮件的了,短信,IM什么的) 原来这个注册的方法也就10多行代码.但 ...
- 【Asp.net之旅】--因自己定义控件注冊而引发的思考
前言 近期在开发远洋的SOA系统平台,开发使用的是.NET平台.对于Asp.net并不困难,但该系统的开发并非全然依靠Asp.net.而是自身封装好的框架.这套框架是远洋地产购买的微软的开发平台,项目 ...