**
yongyinmg的专栏
目录视图
摘要视图
订阅
CSDN博乐 举荐之美 公益活动,感谢你们 从零练就iOS高手实战班震撼来袭 新版极客头条上线,每天一大波干货
使用Autolayout xib实现动态高度的TableViewCell
分类: ios autolayout 2014-09-23 15:48 5133人阅读 评论(0) 收藏 举报
目录(?)[+]
from:http://itony.me/381.html
最近又要做新功能了,虽然没有什么难点,只是获取后端XML数据显示到TableView,但是不是可以更简单快速的完成呢?原来Cell的动态高度一直都是通过sizeWithFont手动计算,潜意识觉得这应该不是最好的实现方式,但由于当时时间紧不允许尝试新技术,所以问题也就遗留了下来,这次又遇到了,时间充裕就解决下吧。
Autolayout是解决自适应frame问题的解决方案(iOS6.0就已经支持了,我现在才用= =#)。通过给视图元素设置合适的约束条件,内部会根据元素内容和限制条件计算出合适的尺寸显示。我们就不用自己手动写这些代码了。
文章步骤看上去有些复杂,真正做起来还是很快的,鼠标拖拽几下就能完成原来的手动计算高度部分代码,减少了很多重复性工作,也让代码看起来更加整洁。
创建Xib文件
首先将Cell做好布局,调整到满意的位置和宽度,然后开始做Autolayout设定。
Autolayout操作方式有两种,一种是选择目标后,使用右下角的工具栏;另一种是直接使用右键拖拽目标,在弹出的菜单中选择限制项。当选择的目标比较小的时候,可以打开左侧的菜单,在这里做拖拽操作一样是可以的。个人感觉后者更方便一些。
开始之前,先来介绍下使用的基本工具吧。
第一个按钮是和对齐有关的,就是控制多个元素(Lable, Button等)的统一约束。例如我们需要让标题和内容按照左,就选择标题和内容元素,选择Leading Edges设置为5即可。
Autolayout_Align
第二个按钮是和元素位置固定有关的限制条件,直接看图吧:
Autolayout_Pin
右侧能够看到当前选择元素限制条件的列表:
Autolayout_Inspector_Constrainsts list
这里有两个参数,“Content Hugging Priority”和“Content Compression Resistance Priority”,感觉不太好理解,栈爆上找到一篇解释,讲的挺好的:Cocoa Autolayout: content hugging vs content compression resistance priority
有时候想要一个元素的间距是一个动态值,例如距离右侧至少10pt(即>=10pt),那么可以在上图中点击右侧按钮(齿轮)进入详细设置:
Autolayout_Constraint_Relation Config
第三个按钮是有关清除限制条件、根据限制更新视图大小的工具。个人比较常用的是清除限制条件,有时候设置错了很麻烦,直接清除掉重新来就行了。
Autolayout_Resolve Auto Layout Issues
上面这些就是常用到的一些限制条件了。个人觉得使用右键拖拽弹出的菜单选择更方便和直观一些,因为菜单中会根据拖拽内容动态显示可用项供我们选择,菜单如图
Autolayout_ShortAction
大致就是这些了吧……
我来谈谈自己的用法。总体上是从上到下,从左到右做约束限制。在这个例子中,就是设置标题->内容->发帖人这样的顺序。
Autolayout_Example
设置标题的顶部和左侧距离,以及宽度(防止超出边界)。
设置内容的顶部(距离标题)和左侧距离,以及宽度。设置最大行数。
设置发帖人的顶部和左侧距离,以及高度。
设置发帖时间的顶部和左侧距离,距离右侧间距(防止内容过长)。
关键步骤,设置发帖人距离底部距离,如果不设置这个参数,那么下面代码计算的Cell高度会永远是0。
多试一试,如果有错误或者缺少限制,XCode会有提示。它报出的错误一般都是必须修正的,但它给的自动修正建议有时并不是我们想要的(正确的),想清楚再添加。
代码部分
使用了xib制作的Cell,那么在原来的项目代码中如何使用呢?看代码:
static NSString *CellIdentifier = @"CellIdentifier";
- (void)viewDidLoad
{
//注册TableView中用于复用的Cell
[self.tableView registerNib:[UINib nibWithNibName:@"BBSPostContentCell" bundle:nil] forCellReuseIdentifier:CellIdentifier];
//...
}
//关键方法,获取复用的Cell后模拟赋值,然后取得Cell高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
BBSPostContentCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *dataSourceItem = [self.dataSource objectAtIndex:indexPath.row];
cell.titleLabel.text = [dataSourceItem valueForKey:@"title"];
cell.contentLabel.text = [dataSourceItem valueForKey:@"body"];
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return height;
}
//在cellForRowAtIndexPath中,按照常规方法做赋值就行了
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
BBSPostContentCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *dic = dataSource[indexPath.row];
cell.titleLabel.text = dic[@"title"];
cell.contentLabel.text = dic[@"body"];
return cell;
}
2014.1.2: 在测试时发现这部分的代码还存在一些性能问题(整个表视图在更新时会卡顿),我会稍后补上。
我在使用Instruments分析发现,heightForRowAtIndexPath中调用dequeueReusableCellWithIdentifier会占用很多CPU资源,因此我试着不使用registerNib方法注册复用Cell,而在代码中手动处理,类似这样:
//内存优化
BBSPostContentCell*cell=[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell=[[NSBundlemainBundle]
loadNibNamed:@"BBSPostContentCell"
owner:self
options:NULL][0];
NSLog(@"cell
loadNibNamed");
}else{
NSLog(@"cell
dequeueReusableCellWithIdentifier");
}
这时我发现这里的Cell调用dequeueReusableCellWithIdentifier方法总是返回nil,因此每次都是从xib中加载,从而耗费了大量的资源。问题的原因我还不清楚,目前我的解决方法是,单独生成一个Cell用于在heightForRowAtIndexPath方法中计算高度。
其次,在[tableView reloadData]和[tableView insertRowsAtIndexPaths]时,底层会将所有行高重新计算,这个会占用大量的时间,因此我试着对行高做了缓存,暂时解决了这个问题。
关于兼容性问题
由于Autolayout只能在iOS6.0以上版本使用,而根据友盟统计,目前6.0以下的用户大概还有8%左右(2013.12)。现在有两个办法解决:
哥不在乎,放弃这些用户!(好霸气=。=)把项目的部署版本修改为6.0以上即可。
咳…咳…这个嘛,用户还是有必要支持的………恩,那我们来说说这个怎么兼容。
思路很简单,我们告诉XCode,6.0以上版本使用Autolayout,以下的旧版本不要使用这个就可以了。
将原xib文件inspector中选择”Interface Builder Document”->”Build for”->”iOS 6.0 and Later”,告诉XCode,这个xib在6.0以上设备编译。
将xib文件拷贝一份副本,命名为”xxx_iOS5.xib”,在inspector中选择”Project Deployment Target”,也就是说使用项目部署目标版本(即最低版本5.0),并取消”Use Autolayout”选项。
在代码中根据系统版本加载不同的xib文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) \
([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define IS_SUPPORT_AUTOLAYOUT SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")
- (void)viewDidLoad
{
if (!IS_SUPPORT_AUTOLAYOUT) {
//for iOS 5.x
[self.tableView registerNib:[UINib nibWithNibName:@"BBSPostContentCell_iOS5" bundle:nil] forCellReuseIdentifier:CellIdentifier];
} else {
[self.tableView registerNib:[UINib nibWithNibName:@"BBSPostContentCell" bundle:nil] forCellReuseIdentifier:CellIdentifier];
}
}
最后别忘了在高度计算时,区分下代码:
1
2
3
4
5
6
7
8
9
10
11
12
-(CGFloat)tableView:(UITableView*)tableView
heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
if(IS_SUPPORT_AUTOLAYOUT){
//Autolayout部分代码,同上
//.....
returnheight;
}else{
//for
iOS 5.x
//为了简单起见,就直接使用固定值了,当然如果你要自己为iOS5用户手动计算动态高度,也是可以的。
return81;
}
}
完成了!
2013的最后一篇文章,元旦快乐!
上一篇
iOS开发常用国外网站清单
下一篇
iOS中代码支持多国语言切换的实现(Xcode5+iOS7)
猜你在找
大数据编程语言:Java基础
Apple Watch开发入门
iOS8开发技术(Swift版):iOS基础知识
Exchange 2013 管理
网络赚钱靠谱项目推荐
iOS开发笔记--UILabel的相关属性设置
IOS通过NSCoding保存实体对象
iOS开发的一些奇巧淫技
UINavigationItem表示UINavigationBar中的控件
将Lua嵌入IOS程序
准备好了么?
跳
吧
!
更多职位尽在 CSDN JOB
iOS开发工程师
上海彩亿信息技术有限公司
|
8-15K/月
我要跳槽
.NET开发工程师
五八同城信息技术有限公司
|
20-40K/月
我要跳槽
php-百度 知识搜索部
百度在线网络技术(北京)有限公司
|
15-30K/月
我要跳槽
靠谱公司呼唤靠谱Java牛人
宜宝康健网络科技有限公司
|
12-24K/月
我要跳槽
查看评论
暂无评论
发表评论
用 户 名:
cjckkk
评论内容:
插入代码
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
核心技术类目
全部主题 Hadoop AWS 移动游戏 Java Android iOS Swift 智能硬件 Docker OpenStack VPN Spark ERP IE10 Eclipse CRM JavaScript 数据库 Ubuntu NFC WAP jQuery BI HTML5 Spring Apache .NET API HTML SDK IIS Fedora XML LBS Unity Splashtop UML components Windows Mobile Rails QEMU KDE Cassandra CloudStack FTC coremail OPhone CouchBase 云计算 iOS6 Rackspace Web App SpringSide Maemo Compuware 大数据 aptech Perl Tornado Ruby Hibernate ThinkPHP HBase Pure Solr Angular Cloud Foundry Redis Scala Django Bootstrap
个人资料
[访问我的空间]
yongyinmg
访问:342679次
积分:4002
等级:
排名:第3583名
原创:11篇
转载:281篇
译文:0篇
评论:63条
文章搜索
文章分类
Ios(262)
ios动画(36)
ios8(13)
ios autolayout(22)
swift(9)
iphone6适配(3)
文章存档
2015年05月(4)
2015年04月(1)
2015年03月(5)
2015年02月(3)
2015年01月(4)
展开
阅读排行
关于IOS的Autolayout特性的理解以及使用(18889)
初探 iOS8 中的 Size Class(15550)
iOS开发技巧(系列十五:autolayout自动布局)(11412)
发布iOS应用(xcode5)到App Store(苹果商店) 详细解析(10279)
iPhone 6 / 6 Plus 设计·适配方案(10160)
iOS8 定位新增功能(9720)
Xcode6的新特性、iPhone6和iPhone6Plus的适配,xcode6iphone6(9517)
百度天气预报接口(8011)
iOS8 Today 实现Clips widget(5234)
使用Autolayout xib实现动态高度的TableViewCell(5115)
评论排行
iOS8 Today 实现Clips widget(12)
初探 iOS8 中的 Size Class(8)
发布iOS应用(xcode5)到App Store(苹果商店) 详细解析(6)
Reveal查看任意app的高级技巧(4)
关于IOS的Autolayout特性的理解以及使用(3)
Reveal:分析iOS UI的利器(3)
iOS8 定位新增功能(3)
Responder Chain(ios事件传递)(3)
Xcode6的新特性、iPhone6和iPhone6Plus的适配,xcode6iphone6(2)
[iOS] 初探 iOS8 中的 Size Class(2)
推荐文章
最新评论
CoreMotion框架-iOS设备的核心运动
tanghaitao000: 请问大神做过实际的测试么?最近在做室内导航,不知道真机误差怎样
iOS8 Today 实现Clips widget
chenyixiu: 你好,怎么点击完widget跳进程序的指定界面呢?我现在只知道点击开启宿主程序。。。
iOS8 Today 实现Clips widget
chenyixiu: 你好,怎么点击完widget跳进程序的指定界面呢?我现在只知道点击开启宿主程序。。。
用UIImagePickerViewController自定义相机界面
在路上奋斗: 完整代码在哪里下载了 楼主?谢谢了 急着参考了
用UIImagePickerViewController自定义相机界面
deally: 完整的代码可以哪里下载
willMoveToParentViewController和didMoveToParentViewController
authorware310: 大神你好,又学习到了,多么深刻的领悟!
willMoveToParentViewController和didMoveToParentViewController
qq_25371283: 大神牛逼
iOS8 Today 实现Clips widget
yongyinmg: @humingtao2013:sorry 我加一下
iOS8 Today 实现Clips widget
MT_Hu-Struggle: .........大哥,你转载文章,起码加上转载链接吧
制作动态及静态Framework
NSObject_: 请问一下,自己制作的动态库运用到应用中是不是不能通过苹果公司审核啊?
公司简介
|
招贤纳士
|
广告服务
|
银行汇款帐号
|
联系方式
|
版权声明
|
法律顾问
|
问题报告
|
合作伙伴
|
论坛反馈
网站客服
杂志客服
微博客服
webmaster@csdn.net
400-600-2320|北京创新乐知信息技术有限公司 版权所有|江苏乐知网络技术有限公司 提供商务支持
京 ICP 证 070598 号|Copyright © 1999-2014, CSDN.NET, All Rights Reserved
GongshangLogo
**
xib自适应高度
最新推荐文章于 2023-09-25 18:03:23 发布