I'm trying to call [cell layoutIfNeeded] and [cell.contentView layoutIfNeeded] as I have a number of subviews that have custom constraint logic that I implement in the cell's layoutSubviews method.
However, despite calling both those methods in cellForRowAtIndexPath, when I check the frames of the subviews in the contentView, their frames are still incorrect. I've ensured to call layoutIfNeeded on each subview as well.
Any ideas on why this is happening? The frames are only correct after the cell is displayed, but the height isn't being calculated properly before that.
edit:
I am trying to use the new auto size feature in iOS 8. It's not resizing properly because I have some complicated logic in terms of where my labels go if one is larger than the other. It's not as simple as stacking the labels together - which is why I need the subviews to be laid out correctly before the height is calculated.
I'm not sure what is happening with the code without more information but you should consider using Auto resizing cells. This will resize your cells automatically without having to deal with layout subviews.
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
The layout subviews solution is still used in some edge cases but was mainly used before UITableViewAutomaticDimension came out.
Related
I managed to get this work in the past but now I cannot remember how I did it. I have a UITableView with a dynamic cell and in it, I have an UIView with a height of 174 as a constraint. However, after running the app, it displays the UIView with less height than I defined and also I am getting this error: Warning once only: Detected a case where constraints ambiguously suggest a height of zero for tableviewcell cell's. We're considering the collapse unintentional and using standard height instead:
Those are the constraints I have in the UIView:
I am not able to find a fix for this.
Use this datasource
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 178
}
I have a design, where UITableView is in UIScrollView with other content and the content is scrolling with the table data. It means, that table has scrolling disabled and is stretched to full size.
I'm using autolayout and the table has height constraint, set to some default value.
Then I have overwritten viewWillLayoutSubviews method:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if (self.itemTableView.contentSize.height > 0) {
self.itemTableViewHeightConstraint.constant = self.itemTableView.contentSize.height
}
}
With this method in place, when I called self.itemTableView.reloadData() after loading the data from the REST, the height constraint was set to table content height, which was great.
This used to work for me in many projects, but for some reason it is not working in the latest one, written in swift 4. Does something changed? Why tableView reloadData() method does not invoke viewWillLayoutSubviews()?
The problem was that the tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) was not calling self.view.setNeedsLayout() before returning row.
I have multiple tableviews in my ViewController and each tableview has different number of rows, please see image below:
Is there any way to match the height of the tableview according to its number of rows?
In your view controller, put code similar to the following:
override func updateViewConstraints() {
super.updateViewConstraints()
tableViewHeightConstraint.constant = tableView.contentSize.height;
}
Where tableViewHeightConstraint is an #IBOutlet to NSLayoutConstraint. Obviously with multiple table views you will need to reference multiple height constraints, so you'd just have one line in updateViewConstraints for each table view you want.
The advantage of this technique is that it takes all of the table view's content into account. It handles grouping, automatic cell height, etc.
You have to determine how many cells you have, then override
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return CGRectGetHeight(self.tableView.bounds) / self.tableView.numberOfRowsInSection(indexPath.section)
}
Btw, I suppose making use of header cells would be a better idea than implementing multiple tableviews.
I'm writing an application where images are downloaded asynchronously and when the images are loaded its scaled but I just want to show as the same size within the UITableViewCell.
Since i'm using auto layout I have tried to change the height constraint through an IB but then I have to change the height of the cell and I though of reloading each cell after downloading each image but not sure if it's a good idea.
Its like the Facebook application where images are loaded and the uitableviewcell is dynamically changed.
Have you tried this delegate method?:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
// return downloadedimage.bounds.height etc.
}
Also do not forget to reload data in the viewDidLoad method
tableView.reloadData()
I am trying to resize a tableviewcell based on the size of a UILabel that can be one or more lines. I need autolayout turned ON for the rest of the app, so I don't want to turn it off to get this working. Target is iOS 7 and iOS 8.
I have tried several solutions, but for some reason I can't seem to get the correct height of the label to automatically adjust or to adjust the cell height.
The problem is occurring in this method: calculateHeightForConfiguredSizingCell. I have put a sample project on Git, so you can see what I am seeing.
https://github.com/mdaymond/cellResizer
This example is based on this article: http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout
Update
I checked in an update to the code. It's ALMOST working the way I want and calculating programatically, but for some reason the label height isn't quite sized correctly - it's not getting the full height required. Problem with the original code was that the label needed an explicit width.
Here we go, if you are supporting IOS 7 then you need to implement UITableViewDelegate protocol in your class and then override:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
}
for more information about Dynamic custom UITableViewCell's height based on label text length (check this out) and you can place the code in the heightForRowAtIndexPath function:
height based on label text length
Also override :
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
// example to return the estimated height
return 280
}
Note : by supporting IOS 7 you should handle it manually. there is no such easier way as IOS 8.
But if you are only supporting IOS 8 and later then you can do it simply in the following two lines :
self.tableView.estimatedRowHeight = 280
self.tableView.rowHeight = UITableViewAutomaticDimension
Actually i have download your source code and doing following changes. and UILabel is now support multiline.
Step 1 : Removed programmatically calculate row height. that means commented heightForRowAtIndexPath in your demo.
Step 2: Set following layout constraints on UILabel in your UITableViewCell.
Step 3 : Set number of line to 0 in your xib.
Output :
Here is my code.
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
self.scoutPropertyTable.rowHeight = UITableViewAutomaticDimension + 35
return self.scoutPropertyTable.rowHeight
}