Template auto layout cell for automatically UITableViewCell height calculating.(Swift 3.0)
DGTemplateLayoutCell copy and modify forkingdog's UITableView-FDTemplateLayoutCell, and it is implemented in Swift 3.0.
- Xcode 7 or higher
- iOS 8.0 or higher (may work on previous versions, just did not test it)
- ARC
- Swift 3.0
Template auto layout cell for automatically UITableViewCell height calculating.
If you have a self-satisfied cell, then all you have to do is:
import DGTemplateLayoutCell
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableView.dg_heightForCellWithIdentifier("DGFeedCell", configuration: { (cell) -> Void in
// Configure this cell with data, same as what you've done in "-tableView:cellForRowAtIndexPath:"
// Like:
// let cell = cell as! DGFeedCell
// cell.loadData(self.feedList[indexPath.section][indexPath.row])
})
}
Since iOS8, -tableView:heightForRowAtIndexPath:
will be called more times than we expect, we can feel these extra calculations when scrolling. So we provide another API with cache by index path:
import DGTemplateLayoutCell
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableView.dg_heightForCellWithIdentifier("DGFeedCell", indexPath: indexPath, configuration: { (cell) -> Void in
// Configure this cell with data, same as what you've done in "-tableView:cellForRowAtIndexPath:"
// Like:
// let cell = cell as! DGFeedCell
// cell.loadData(self.feedList[indexPath.section][indexPath.row])
})
}
Or, if your entity has an unique identifier, use cache by key API:
import DGTemplateLayoutCell
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return tableView.dg_heightForCellWithIdentifier("DGFeedCell", key: uuid, configuration: { (cell) -> Void in
// Configure this cell with data, same as what you've done in "-tableView:cellForRowAtIndexPath:"
// Like:
// let cell = cell as! DGFeedCell
// cell.loadData(self.feedList[indexPath.section][indexPath.row])
})
}
FDTemplateLayoutCell
offers 2 modes for asking cell's height.
- Auto layout mode using "-systemLayoutSizeFittingSize:"
- Frame layout mode using "-sizeThatFits:"
Generally, no need to care about modes, it will automatically choose a proper mode by whether you have set auto layout constrants on cell's content view. If you want to enforce frame layout mode, enable this property in your cell's configuration block:
cell.dg_enforceFrameLayout = true
And if you're using frame layout mode, you must override -sizeThatFits:
in your customized cell and return content view's height (separator excluded)
override func sizeThatFits(size: CGSize) -> CGSize {
// var height: CGFloat = 0
// height += self.contentLabel.sizeThatFits(size).height
// height += self.contentLabel.sizeThatFits(size).height
// height += self.contentImageView.sizeThatFits(size).height
// height += self.userNameLabel.sizeThatFits(size).height
// height += self.timeLabel.sizeThatFits(size).height
return CGSizeMake(size.width, height)
}
Debug log helps to debug or inspect what is this "FDTemplateLayoutCell" extention doing, turning on to print logs when "calculating", "precaching" or "hitting cache".Default to "false", log by "print".
self.tableView.dg_debugLogEnabled = true
It will print like this:
calculate using auto layout - 388.666666666667
cached by indexPath:[0,4] --> 388.666666666667
layout cell created - DGFeedCell
calculate using auto layout - 338.666666666667
cached by indexPath:[0,5] --> 338.666666666667
layout cell created - DGFeedCell
calculate using auto layout - 371.666666666667
cached by indexPath:[0,6] --> 371.666666666667
layout cell created - DGFeedCell
calculate using auto layout - 242.333333333333
cached by indexPath:[0,7] --> 242.333333333333
hit cache by indexPath:[0,0] -> 125.333333333333
hit cache by indexPath:[0,0] -> 125.333333333333
hit cache by indexPath:[0,1] -> 147.0
hit cache by indexPath:[0,1] -> 147.0
hit cache by indexPath:[0,2] -> 352.0
hit cache by indexPath:[0,2] -> 352.0
a fully self-satisfied cell is constrainted by auto layout and each edge("top", "left", "bottom", "right") has at least one layout constraint against it. It's the same concept introduced as "self-sizing cell" in iOS8 using auto layout.
A bad one :( - missing right and bottom
A template layout cell is created by -dequeueReusableCellWithIdentifier:
method, it means that you MUST have registered this cell reuse identifier by one of:
- A prototype cell of UITableView in storyboard.
- Use
-registerNib:forCellReuseIdentifier:
- Use
-registerClass:forCellReuseIdentifier:
原作者(sunnyxx)文章: http://blog.sunnyxx.com/2015/05/17/cell-height-calculation/
Latest version: 1.1.2
pod search DGTemplateLayoutCell
pod 'DGTemplateLayoutCell', '~> 1.1.2'
If you cannot search out the latest version, try:
pod setup
We recommend to use the latest release in cocoapods.
- 1.0
- Modify FDTemplateLayoutCell
- Writes in Swift 2.0
- 1.1
- Fix some bugs.
- 1.1.1
- Add Some Comment and modify podspec
- 1.1.2
- Support Swift 3.0
MIT