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

简介

本文中,我们将一起使用 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 已经可以根据图片和文字中比较高的一个完全自适应。

时间: 2024-10-17 13:14:14

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

Auto Layout 使用心得

此系列文章代码仓库在 https://github.com/johnlui/AutoLayout ,有不明白的地方可以参考我的 Auto Layout 设置哦,下载到本地打开就可以了. 简介 Auto Layout 是苹果在 Xcode 5 (iOS 6) 中新引入的布局方式,旨在解决 3.5 寸和 4 寸屏幕的适配问题.屏幕适配工作在 iPhone 6 及 plus 发布以后变得更加重要,而且以往的“笨办法”的工作量大幅增加,所以很多人开始学习使用 Auto Layout 技术. 初体验 0.

【转】有了Auto Layout,为什么你还是害怕写UITabelView的自适应布局?

Apple 算是最重视应用开发体验的公司了.从Xib到StoryBoard,从Auto Layout到Size Class,每一次的更新,都会给iOS应用的开发带来不小的便利.但是,对于绝对多数iOS攻城狮来说,我们依然还是很害怕写UITabelVIew的自适应布局.当然,害怕不是因为我们不会写,或者本身有什么特殊的技术点,而是因为太麻烦.当然,文章的后半部分,会给出相应的解决方案,毕竟本文不是为了吐槽而吐槽. UITabelView的自适应布局有多麻烦? 数据类型的不确定性:种类越多,页面越复

iOS 开发实践之 Auto Layout

原:http://xuexuefeng.com/autolayout/?utm_source=tuicool 本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自动布局)在实际项目中的使用. Auto Layout 在 2012 年的 iOS 6 中发布,距今已经 2 年多了,如果从 2011 年在 Mac OS X 上发布的 Auto Layout 开始算起,已经超过 3 年了.如果你的简历上写着 2 年以上工作经验,而竟然不会使用 Auto Layout

iOS 开发实践之Auto Layout(From Vincent Sit)

本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自动布局)在实际项目中的使用. Auto Layout 在 2012 年的 iOS 6 中发布,距今已经 2 年多了,如果从 2011 年在 Mac OS X 上发布的 Auto Layout 开始算起,已经超过 3 年了.如果你的简历上写着 2 年以上工作经验,而竟然不会使用 Auto Layout,真有点不可思议. 本文将会通过若干个 Demo 进行讲解,通过实践来理解 Auto Layout 到底是什么

iOS6 自动布局 入门–Auto Layout

目前为止,即使你的界面设计是在合理的复杂度内,你也必须要为之写许多代码来适应变化的布局.现在我相信你会很高兴听到这种情况将不会发生了-对于iPhone与iPad IOS6 带来了一个非常了不起的特征:自动布局. 自动布局不仅能给你的应用带来各种屏幕尺寸设计的支持,做为额外的惊喜,它还能使设计中的各种小事比如多语言环境支持.你从此不必再为你想要支持的各种语言重新设计nibs和storyboards文件,当然这也包括一些从右至左书写的语言比如说希伯来文和阿拉伯语. 这篇教程将向你展示的是如何开始使用

Swift语言Auto Layout入门教程

Swift语言Auto Layout入门教程:上篇 开始用自动布局约束的方式思考吧! 更新记录:该教程由Brad Johnson更新Swift和iOS 8内容,原文第一版作者为教程编纂组的Matthijs Hollemans. 你可曾为了让App在横竖屏模式下都能展现整洁的界面而感到苦恼?你可曾为了让布局同时支持iPhone和iPad而感到心烦?别灰心,好消息来啦! 为某种确切尺寸的屏幕设计用户界面并不麻烦,但如果屏幕画面的框架不固定,为适应新环境,App中各个UI元素的位置和大小都需要相应调整

iOS7 自动布局 入门–Auto Layout

目前为止,即使你的界面设计是在合理的复杂度内,你也必须要为之写许多代码来适应变化的布局.现在我相信你会很高兴听到这种情况将不会发生了-对于iPhone与iPad IOS6 带来了一个非常了不起的特征:自动布局. 自动布局不仅能给你的应用带来各种屏幕尺寸设计的支持,做为额外的惊喜,它还能使设计中的各种小事比如多语言环境支持.你从此不必再为你想要支持的各种语言重新设计nibs和storyboards文件,当然这也包括一些从右至左书写的语言比如说希伯来文和阿拉伯语. 这篇教程将向你展示的是如何开始使用

有了Auto Layout,为什么你还是害怕写UITabelView的自适应布局?

本文转载至 http://www.cnblogs.com/ios122/p/4832859.html Apple 算是最重视应用开发体验的公司了.从Xib到StoryBoard,从Auto Layout到Size Class,每一次的更新,都会给iOS应用的开发带来不小的便利.但是,对于绝对多数iOS攻城狮来说,我们依然还是很害怕写UITabelVIew的自适应布局.当然,害怕不是因为我们不会写,或者本身有什么特殊的技术点,而是因为太麻烦.当然,文章的后半部分,会给出相应的解决方案,毕竟本文不是

debugging Auto Layout:Debugging Tricks and Tips

Debugging Tricks and Tips调试技巧和技巧 The following topics describe techniques for gathering and organizing information about your layout, as well as descriptions of some surprising behaviors you may encounter. You may not need to use these techniques on