本文中,咱们将一块儿使用 Auto Layout 技术,让 UITableViewCell 的高度随其内部的 UILabel 和 UIImageView 的内容自动变化。swift
放置一个按钮,恢复到 firstTableViewController 的链接:app
别忘了添加约束让他居中哦。ide
将 firstTableViewCell 的尺寸设置为 600 * 81,将 logo 的尺寸设置为 80 * 80。将 logo 的约束修改成以下图所示:性能
修改 label 的尺寸和位置,添加约束以下图:spa
为了便于返回。操做以下图:prototype
选中 label,设置 lines 行数为 0,表示不限长度自动折行:code
修改 label 的文字内容让其超出一行:orm
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 } }
estimatedHeightForRowAtIndexPath 是 iOS 7 推出的新 API。若是列表行数有一万行,那么 heightForRowAtIndexPath 就会在列表显示以前计算一万次,而 estimatedHeightForRowAtIndexPath 只会计算当前屏幕中显示着的几行,会大大提升数据量很大时候的性能。对象
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 ......
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 }
上面让 firstTableViewCell 根据 label 自动计算高度的过程当中,有一个超级大坑:若是给左侧 UIImageView 赋的图片较大(大于 80px),将看到以下奇怪的结果:图片
首先,把图片的渲染模式改为 Aspect Fit:
给 Images.xcassets 增长三张图片,命名为 0、一、2,尺寸从小到大:
给 cellForRowAtIndexPath 增长代码:
if indexPath.row < 3 { cell.logoImageView.image = UIImage(named: indexPath.row.description) }
查看效果:
新建一个 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 已经能够根据图片和文字中比较高的一个彻底自适应。