Reputation: 336
I've a tableView with custom cells. Each cell has different interface, elements. All they have different sizes. Each cell has different type of elements and their count. All these elements are created dynamically, so I'm creating them, making their frames and adding as subviews.
So the problem that heightForRowAtIndexPath executes before cellForRowAtIndexPath where I'm creating the row and constructing its interface and I don't know how to pass calculated height to heightForRowAtIndexPath
How can I count row height before and pass its value to heightForRowIndexPath for correct drawing of my tableView?
Upvotes: 5
Views: 3747
Reputation: 151
UITableViewCell
.UIView
, which is put in a cell.NSLayoutConstraint
, one from UIView.top
to top of the cell, the second from UIView.bottom
to the bottom of the cell and the third - the height of the UIView
.viewDidLoad
method of tableViewController
set row height as the UITableViewAutomaticDimension
:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = UITableViewAutomaticDimension
}
:
func adjustHeightOfInnerView() {
let height = 100
self.myInnerCellViewHeightConstraint.constant = height
self.contentView.setNeedsUpdateConstraints()
}
cellForRowAtIndexPath
call the adjustHeightOfTableview
::
func tableView (tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! myTableViewCellSubclass
cell.adjustHeightOfTableview()
return cell
}
Upvotes: 0
Reputation: 1709
If your cell view is really very complex and every component's height are depending on data source. You can try to create the view in heightForRowIndexPath
method and then cache the created view to a dictionary in your view controller and use it directly in cellForRowAtIndexPath
. In this way you only need to create the view once when user scrolling the table. If the datasource is not changing very frequently, you can reuse the cached view in heightForRowIndexPath
as well.
And if the tableview has a lot of rows, you should return an approximate value for height in estimatedHeightForRowAtIndexPath
to speed up the loading process of the view controller. Otherwise during loading tableview, it will try to calculate all row's height which may requires a lot of time.
But I really don't think your cell would be so complex. If only some UITextLabels that depends on datasource for the height, you can simply only calculate the height for the label, then add it to other components' height which is fixed.
Upvotes: 3
Reputation: 229
You really should consider subclassing UITableViewCell and adding your custom logic inside your subclass.
Starting from there, you'll have such options:
Create static method in your cell that will receive all data necessary to draw your cell (e.g heithtForCellWithFirstString:secondString:accessoryImage etc) and calculate height using string size computation methods. Use this method inside heightForRowAtIndexPath.
Use autolayout for laying out subviews of your cell and then set table view's row height property to UITableViewAutomaticDimension. This way you won't need heightForRow delegate method at all. There are plenty of tutorials on this, for example: http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift
Upvotes: 2