原文网址: http://lvwenhan.com/ios/449.html

此系列文章代码仓库在 https://github.com/johnlui/AutoLayout ,有不明白的地方可以参考我的 Auto Layout 设置哦,下载到本地打开就可以了。

简介

本文中,我们将一起使用 Auto Layout 技术,让 UITableViewCell 的高度随其内部的 UILabel 和 UIImageView 的内容自动变化。

搭建界面

恢复之前删除的按钮

放置一个按钮,恢复到 firstTableViewController 的连接:

别忘了添加约束让他居中哦。

修改 firstTableViewCell

将 firstTableViewCell 的尺寸设置为 600 * 81,将 logo 的尺寸设置为 80 * 80。将 logo 的约束修改为如下图所示:

修改 label 的尺寸和位置,添加约束如下图:

给 ViewController 增加 UINavigationController 嵌套

为了便于返回。操作如下图:

查看结果

根据 label 自动计算 firstTableViewCell 高度

选中 label,设置 lines 行数为 0,表示不限长度自动折行:

修改 label 的文字内容让其超出一行:

import UIKit

class firstTableViewController: UITableViewController {

    var labelArray = Array<String>() // 用于存储 label 文字内容

    override func viewDidLoad() {
super.viewDidLoad() var nib = UINib(nibName: "firstTableViewCell", bundle: nil)
self.tableView.registerNib(nib, forCellReuseIdentifier: "firstTableViewCell") // 循环生成 label 文字内容
for i in 1...10 {
var text = ""
for j in 1...i {
text += "Auto Layout"
}
labelArray.append(text)
}
} override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
} // MARK: - Table view data source override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 50
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
} override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return labelArray.count
} override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("firstTableViewCell", forIndexPath: indexPath) as! firstTableViewCell cell.firstLabel.text = labelArray[indexPath.row] return cell
}
}

现在到了最关键的时刻,驱动 UITableViewCell 适应 Label 内容:

1. 使用 estimatedHeightForRowAtIndexPath 替代 heightForRowAtIndexPath

estimatedHeightForRowAtIndexPath 是 iOS 7 推出的新 API。如果列表行数有一万行,那么 heightForRowAtIndexPath 就会在列表显示之前计算一万次,而 estimatedHeightForRowAtIndexPath 只会计算当前屏幕中显示着的几行,会大大提高数据量很大时候的性能。

2. 新建一个 prototypeCell 成员变量以复用,并在 viewDidLoad 中初始化

class firstTableViewController: UITableViewController {

    var labelArray = Array<String>() // 用于存储 label 文字内容

    var prototypeCell: firstTableViewCell!

    override func viewDidLoad() {
super.viewDidLoad() var nib = UINib(nibName: "firstTableViewCell", bundle: nil)
self.tableView.registerNib(nib, forCellReuseIdentifier: "firstTableViewCell") // 初始化 prototypeCell 以便复用
prototypeCell = tableView.dequeueReusableCellWithIdentifier("firstTableViewCell") as! firstTableViewCell ......

3. 计算出高度

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let cell = prototypeCell
cell.firstLabel.text = labelArray[indexPath.row]
return cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height + 1
}

4. 查看效果

超级大坑

上面让 firstTableViewCell 根据 label 自动计算高度的过程中,有一个超级大坑:如果给左侧 UIImageView 赋的图片较大(大于 80px),将看到如下奇怪的结果:

这只是因为图片把 UITableViewCell 撑大了,并不是我们的计算没有效果。

解决大坑:进攻是最好的防守!根据图片自动计算 firstTableViewCell 高度

首先,把图片的渲染模式改成 Aspect Fit:

给 Images.xcassets 增加三张图片,命名为 0、1、2,尺寸从小到大:

给 cellForRowAtIndexPath 增加代码:

if indexPath.row < 3 {
cell.logoImageView.image = UIImage(named: indexPath.row.description)
}

查看效果:

前 两个 cell 看起来比较正常,第三个为什么多出了那么多空白?这就是使用 Auto Layout 限制图片宽度为 80px 的原生问题:宽度虽然限制了,高度却依然是原图的高度。

解决办法也很简单:如果图片宽度大于 80px,就重绘一张 80px 宽度的图片填充进去。

新建一个 Group(虚拟文件夹),叫 Extensions,并在其内部新建 UIImage.swift 文件,内容如下:

import UIKit

extension UIImage {
func resizeToSize(size: CGSize) -> UIImage {
UIGraphicsBeginImageContext(size)
self.drawInRect(CGRectMake(0, 0, size.width, size.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext() return newImage
}
}

给 UIImage 类扩展了一个名为 resizeToSize 的方法,返回一个按照要求的大小重绘过的 UIImage 对象。修改 cellForRowAtIndexPath 的代码为:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("firstTableViewCell", forIndexPath: indexPath) as! firstTableViewCell cell.firstLabel.text = labelArray[indexPath.row] var image = UIImage(named: (indexPath.row % 3).description)!
if image.size.width > 80 {
image = image.resizeToSize(CGSizeMake(80, image.size.height * (80 / image.size.width)))
}
cell.logoImageView.image = image return cell
}

搞定!

查看效果

从上图可以看出,cell 已经可以根据图片和文字中比较高的一个完全自适应。

 
 

AutoLayout 根据文字、图片自动计算 UITableViewCell 高度的更多相关文章

  1. 自动计算UITableViewCell高度2(CGRect约束)

    1.先创建model .h #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface LBDNe ...

  2. 使用第三方《UITableView+FDTemplateLayoutCell》自动计算UITableViewCell高度(Masonry约束)

    直接上代码: 1:先自定义cell .h文件中 #import <UIKit/UIKit.h> #import "LBDNewMsgListModel.h" #impo ...

  3. UITableViewCell高度自适应探索--AutoLayout结合Frame

    UITableViewCell高度自适应探索--UITableView+FDTemplateLayoutCell地址: http://www.jianshu.com/p/7839e3a273a6UIT ...

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

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

  5. UITableViewCell 高度计算从混沌初始到天地交泰

    [原创]UITableViewCell 高度计算从混沌初始到天地交泰 本文主要基予iOS UITableViewCell 高度自适应计算问题展开陈述,废话少说直入正题: UITableView控件可能 ...

  6. 优化UITableViewCell高度计算的那些事

    优化UITableViewCell高度计算的那些事 我是前言 这篇文章是我和我们团队最近对 UITableViewCell 利用 AutoLayout 自动高度计算和 UITableView 滑动优化 ...

  7. uitableviewcell高度自适应笔记

    今天看了几篇uitableviewcell高度自适应的文章,大体分为两种方式. 第一种方式,cell里面有label,在cellforrow绘制的时候计算Label的可能高度,并且在此时重新计算cel ...

  8. 优化UITableViewCell高度计算的那些事(RunLoop)

    这篇总结你可以读到: UITableView高度计算和估算的机制 不同iOS系统在高度计算上的差异 iOS8 self-sizing cell UITableView+FDTemplateLayout ...

  9. 《转》优化UITableViewCell高度计算的那些事

    我是前言 这篇文章是我和我们团队最近对 UITableViewCell 利用 AutoLayout 自动高度计算和 UITableView 滑动优化的一个总结.我们也在维护一个开源的扩展,UITabl ...

随机推荐

  1. 我们将要建立的EasyDarwin开源社区

    从12年12月我开始建立EasyDarwin开源项目,已经三年多的时间了,从开始最简单的一个开源流媒体服务器项目,如今已经发展成为目前国内最大的一个流媒体开源社区,截至目前已经有十几个项目在Githu ...

  2. Extjs form 表单的 submit

    说明:extjs form表单的提交方式是多种多样的,本文只是介绍其中的一种方法,本文介绍的方法可能不是完美的,但是对于一般的应用应该是没有问题的.     本文包括的主要内容有:form面板设计.f ...

  3. Colly provides a clean interface to write any kind of crawler/scraper/spider

    Scraping Framework for Golang http://go-colly.org/ https://github.com/gocolly/colly package main imp ...

  4. iOS开发隐藏键盘方法总结

    以下为大家带来我整理总结的几种隐藏键盘的方法. 一.隐藏自身软键盘 当对于有多个UITextField控件都想通过点击"Return"来隐藏自身软键盘的情况,这时的最好办法是使用D ...

  5. 周期性计划(一个cron守护进程):

    周期性计划(一个cron守护进程): root@ubuntu:/etc# ps -ef | grep cron root 903 1 0 16:25 ? 00:00:00 /usr/sbin/cron ...

  6. Shell之历史操作记录与欢迎信息

    history: ~/.bash_history:用于记录所有的操作记录 欢迎信息:/etc/issue,只对本地登录生效. 远程终端的欢迎信息:/etc/issue.net

  7. [haoi2011]a

    一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低.”问最少有几个人没有说真话(可能有相同的分数) 题解:首先,由每个人说的话的内容,我们可以理解为他处在ai+1,n-bi ...

  8. 盒子的display属性

    <body> <div style="display:inline">Box-1</div> <div style="displ ...

  9. STL版 括号匹配(感觉不如之前自己用数组模拟的跑的快)

    数据结构实验之栈四:括号匹配 Time Limit: 1000MS Memory limit: 65536K 题目描述  给你一串字符,不超过50个字符,可能包括括号.数字.字母.标点符号.空格,你的 ...

  10. python 快速排序 qsort

    def qsort(arr, start, end): if start > end: return def partition(arr, start, end): pivot = arr[st ...