文档章节

Auto Layout 使用心得(五)—— 根据文字、图片自动计算 UITableViewCell

Gong_xiao
 Gong_xiao
发布于 2015/10/28 17:03
字数 933
阅读 29
收藏 0

简介

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

搭建界面

恢复之前删除的按钮

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

Image

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

修改 firstTableViewCell

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

Image

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

Image

给 ViewController 增加 UINavigationController 嵌套

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

Image

查看结果

Image

根据 label 自动计算 firstTableViewCell 高度

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

Image

修改 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. 查看效果

Image

超级大坑

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

Image

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

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

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

Image

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

Image

给 cellForRowAtIndexPath 增加代码:

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

查看效果:

Image

前两个 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 }

搞定!

查看效果

Image

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


本文转载自:https://lvwenhan.com/ios/449.html

上一篇: block weak
下一篇: 图片拉伸
Gong_xiao
粉丝 2
博文 56
码字总数 7990
作品 0
南京
私信 提问
有了Auto Layout,为什么你还是害怕写UITabelView的自适应布局?

Apple 算是最重视应用开发体验的公司了.从Xib到StoryBoard,从Auto Layout到Size Class,每一次的更新,都会给iOS应用的开发带来不小的便利.但是,对于绝对多数iOS攻城狮来说,我们依然还是很害怕...

ios122
2015/09/23
99
0
UITableView的优化原理

当我们下啦一个 UITableView时,如果没有做优化,只是简单的实现功能代码如下,这样当我们有上百条tableviewcell的时候,我们滑动的非常快时会非常费内存,当然苹果公司不会让我们这样干,苹...

哥特复心
2013/11/29
5.3K
3
优化UITableViewCell高度计算的那些事

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

SunGiantor
2015/05/21
200
2
iOS开发tips-UITableView、UICollectionView行高/尺寸自适应

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jianxin160/article/details/55002487 UITableView 我们都知道UITableView从iOS 8开始实现行高的自适应相对比...

KenshinCui
2017/02/12
0
0
关于UITableView你知道多少——UITableView简单解析

转自萧宸宇的博客 UITableView是在iOS开发中,展示大量内容的首选。我个人认为的原因有以下几点: 1.UITableView的展现形式是为移动设备专门设计过的。有较好的人机交互体验。 2.从技术角度来...

浪子艾菲儿
2013/08/07
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

Go 关闭 channel 的 close 方法

在 Go 中我们所以 close() 来关闭一个 channel 官方的注释如下 The close built-in function closes a channel, which must be either bidirectional or send-only. It should be executed o......

mickelfeng
21分钟前
3
0
语音转文字什么方法比较简单

在很多时候一些比较重要的对话需要录制下来,在录制完成后还需要整理出文字,可是长时间的录音内容想要整理出文字是非常的麻烦的。需要花费大量的时间将录制的声音转换成文字,那么想要简单快...

401恶户
25分钟前
5
0
IIS7配置thinkphp5项目到public目录下

有个项目,tp5写的,要配置到项目的public目录下,一开始报错了...后面删除了配置,重新配置成功了,记录一下过程 1.首先,将网站根目录变为你的public目录下 2.添加解析程序的CGI,这里选择你需要解...

老bia同学
29分钟前
10
0
Redis主从复制的配置和实现原理

Redis的持久化功能在一定程度上保证了数据的安全性,即便是服务器宕机的情况下,也可以保证数据的丢失非常少。通常,为了避免服务的单点故障,会把数据复制到多个副本放在不同的服务器上,且...

TurboSanil
31分钟前
8
0
counsul 集群

1 master节点 cat << EOF > /lib/systemd/system/consul.service[Unit]Description=consul-masterAfter=network-online.target [Service]ExecStart=/bin/sh -c 'consul agent ......

拜了个拜
31分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部