How to get height of UITableView when cells are dynamically sized?
I finally hacked out a solution:
tableView.contentSize.height
will not work for dynamic cells because they will only return the number of cells * estimatedRowHeight
.
Hence, to get the dynamic table view height, you look for all visible cells, and sum up their heights. Note that this only works for table views that are shorter than your screen.
However, before we do the above to look for visible cells, it is important to know that note we need to get the table view on the screen so that we can obtain visible cells. To do so, we can set a height constraint for the table view to some arbitrarily large number just so it appears on the screen:
Set height of table view constraint:
// Class variable heightOfTableViewConstraint set to 1000
heightOfTableViewConstraint = NSLayoutConstraint(item: self.tableView, attribute: .height, relatedBy: .equal, toItem: containerView, attribute: .height, multiplier: 0.0, constant: 1000)
containerView.addConstraint(heightOfTableViewConstraint)Call tableView.layoutIfNeeded(), and when completed, look for the visible cells, sum up their height, and edit the
heightOfTableViewConstraint
:UIView.animate(withDuration: 0, animations: {
self.tableView.layoutIfNeeded()
}) { (complete) in
var heightOfTableView: CGFloat = 0.0
// Get visible cells and sum up their heights
let cells = self.tableView.visibleCells
for cell in cells {
heightOfTableView += cell.frame.height
}
// Edit heightOfTableViewConstraint's constant to update height of table view
self.heightOfTableViewConstraint.constant = heightOfTableView
}
Dynamic UITableView height
You need to set an IBOutlet to the NSLayoutConstraint
that sets the tableView
height (first you need create the height constraint with any value, doesn't matter) and then ctrl drag it to your class file
Then in your viewWillAppear
you have to calculate the tableView
height and set it. Like this:
var tableViewHeight:CGFloat = 0;
for (var i = tableView(self.tableView , numberOfRowsInSection: 0) - 1; i>0; i-=1 ){
tableViewHeight = height + tableView(self.tableView, heightForRowAtIndexPath: NSIndexPath(forRow: i, inSection: 0) )
}
tableViewHeightLayout.constant = tableViewHeight
And that's pretty much it. That will give your scrollView content size and shouldn't raise any warnings.
UITableView with dynamic height
You need to use intrinsicContentSize
variable of a UITableView.
intrinsicContentSize will give us table height.
Create a subclass for child tableView and override
intrinsicContentSize.
Dynamic row heights of a UITableView inside a UITableViewCell
Setting the height of the UITableView when the height of the cells is dynamic
You can try this
// add observer to your tableView to get its proper height when its
//data is loaded. you can do this in view did load
self.YourTableView.addObserver(self, forKeyPath: "contentSize",options: .new, context: nil)
// override this metod to observe for tableView height change
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?){
if(keyPath == "contentSize"){
if let newvalue = change?[.newKey]
{
let newsize = newvalue as! CGSize
// make height constraint for your table view and set to new size.
// and here you can check if newSize.height is more than required tha you can set it to default
if(newsize.height < defaultHeight)
self.tableViewHeightConstraint.constant = newsize.height
}else{
self.tableViewHeightConstraint.constant = defaultHeight
}
}
}
Let me know if you face any trouble
And remember to remove observer otherwise app will crash
deinit {
self.YourTableView.removeObserver(self, forKeyPath: "contentSize")
}
How to use dynamic height of UITableViewCell in auto-layout and move other views to up when bottom view is hidden?
At first, make the height of UITableViewCell to UITableView.automaticDimension
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
Embed all of your questionLabels in a UIStackView
(vertical) excluding bottomLabel
. Set AutoLayoutConstraint between UIStackView
and bottomLabel
.
Set the numberOfLines
property of UILabel
s to 0(zero).
Set the Distribution of the UIStackView
as Fill
Then, in your tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
method hide the labels. And it will automatically handle the spaces between UILabel
s
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! MyCell
cell.questionLabel1.text = labelOneText[indexPath.row]
cell.questionLabel2.text = labelTwoText[indexPath.row]
cell.questionLabel3.text = labelThreeText[indexPath.row]
if labelOneText[indexPath.row] == "" {
cell.questionLabel1.isHidden = true
}
if labelTwoText[indexPath.row] == "" {
cell.questionLabel2.isHidden = true
}
if labelThreeText[indexPath.row] == "" {
cell.questionLabel3.isHidden = true
}
return cell
}
Final Output:
Related Topics
How to Add Spacing Between Uitableviewcell
Remove Alpha Channel in an Image
Undefined Symbols For Architecture Armv7
Check For Internet Connection With Swift
How to Detect That an iOS App Is Running on a Jailbroken Phone
Get to Uiviewcontroller from Uiview
How to Get Current Location from User in Ios
How to Find Specific Subclass of Nsmanagedobject
How to Write a File to a Folder Located At Apple'S Files App in Swift
How to Record Video of Front and Back Camera At a Time in Ios
How to Create Custom Calendar in React Native
How to Size a Uitextview to Its Content
How to Debug Memory Leaks When Leaks Instrument Does Not Show Them
Ios Launching Settings -≫ Restrictions Url Scheme
How to Localise a String Inside the iOS Info.Plist File