Why is tableView cell not dynamic? - ios

Update:
I have found that the problem occurs because of the date labels top constraint when removed the wrapped text becomes visible. The issue is then the date label is under the other text. Could the real problem be that the cell is not dynamically changing based on the constraints?
I am trying to make text in a UILabel to wrap (at the same time I am trying to make the cell change based on the text)
In the .xib I setup the cell, doing this:
self.notifInfoLabel.numberOfLines = 0
self.notifInfoLabel.lineBreakMode = .byWordWrapping
sizeToFit is called right before returning the cell in the delegate method.
cell.notifInfoLabel.sizeToFit()//EDIT: turns out this is not needed
return cell
}
The configure method is called on viewDidLoad and right before .reloadData()
func configureTableView() {
self.tableView.estimatedRowHeight = 82
self.tableView.rowHeight = UITableView.automaticDimension
}
Currently, the text in the label seems to wrap underneath the date label...
How can I make it work as intended?

You have confusing constraints for Auto layout engine.
You want some space from bottom of image view if text is small , And
you want text to dynamic in that case label should grow.
Solution is very simple.
Bottom constraint of Imageview change = to >= with 750 priority
Bottom constraint of Date change = to >=
Hope it is helpful

Related

Xcode: Table View Cell not automatically adjusting its height

I'm having a problem with my table view cells as they do not adjust automatically with its content.
I have a label for a title and another label for a name. There is a text view below the two labels which is never displayed when the simulator runs.
This is
what the Table View Cell is supposed to look like, however, this is what the Table View Cell displays.
I have pinned all elements inside the table view cell to the content view using constraints. I read up that adjusting the table view cell height itself will not work, so, I have to adjust the height from the table view itself.
It is set to automatic but it is not adjusting as seen here. I have also tried to set the estimated height to automatic but to no avail. The only solution was to set a custom height but it would look extremely weird if the text view contains only a few text as there would be a large white space. I did not add any code at all to adjust the size.
These are the following constraints:
Table View
Name Label
Title Label
Text View
First You need to add height constraint for textview and add its IBOUTlet then you need to override the updateconstraint of cell and do following in update constraints method.
override func updateConstraints() {
super.updateConstraints()
self.textViewHeightConstraint.constant = self.textView.contentSize.height
}
and also for name label add bottom constraint.
By default the UITextView will not resize itself to fit its content. While you could use #Waqas Sultan approach, I would recommend to let the textView size itself. To achieve that, just use this:
textView.isScrollEnabled = false
Or, in storyboards, find the Scroll Enabled attributed and uncheck it.
This would make textView to size itself.
However, from the constraints you show it is hard to tell if there are really enough constraints to determine the proper frames for all the content - there are constraints related to Review label, but who knows how you constrained that label.
Not seeing all the relevant constraints in the tableView cell, I cannot guarantee that this will be enough to make it work as you expect (you might have forgotten about just a single one constraint, and it might be messing up your whole layout).
Hey buddy i would like you to try this way.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == desiredIndexPath { // the index where you want automatic dimension
return UITableViewAutomaticDimension
} else {
return 100 // the height of every other cell.
}
}
note: Make sure that you do not give height to the label. Otherwise the label wont expand according to content.

How to Add Margin Between UITableViewCells Without Being Hacky

A lot of the solutions I've seen here include changing the cell's background to an image and using sections for rows rather than just rows themselves. I'm looking to have only two sections and have each cell expand in height on tap, so neither of those solutions would work.
I saw one solution includes setting the frame of the cell in the layoutSubviews() function like so:
override func layoutSubviews() {
super.layoutSubviews()
self.frame = CGRectOffset(self.frame, 0, 10);
}
When I do this however, it only gives margin to one cell and that's only when I tap on the cell.
Is there a surefire way to add spacing in between UITableViewCells without being hacky and breaking the cell layouts in the process?
I did this yesterday pretty easily with auto layout.
I set the background of the cell and it's content view to clear, then I created a new view and setup constraints all around it and put my labels inside of it. The height changes dynamically based on the label so I needed to use UITableViewAutomaticDimension for the row height and give it an estimated row height as well.
I don't see why this wouldn't work for expanding it on a tap as well, you just might have to reload the cell.
make the cell and it's contentView transparent
contentView addSubview customContentView and layout your cell on customContentView
customContentView pin to contentView top leading trailing with offset 0 but pin to bottom with offset 10 //the margin height

UILabel with 0 lines doesn't initially show full text

In my UITableViewCell, when I load data into it, I have 2 UILabels which can have an unlimited number of lines.
I handle both of them like this:
label.numberOfLines = 0
label.lineBreakMode = .ByWordWrapping
When I initially load data into the UITableView, for some reason sometimes the cells on the screen don't yet show the whole String in the labels. Instead they just don't enlarge themselves.
However, when I scroll down so that they're off the screen and then scroll back up, everything looks perfect.
Why is this? How do I fix this issue?
In my cellForRowAtIndexPath I basically use dequeueReusableCellWithIdentifier(:forIndexPath:)
then, I do cell.configureViews(...) and return.
In my PostCell I do the label editing above in the override func layoutSubviews()
You might have forgotten to set the 0 lines property on the storyboard too...
Go to your Storyboard, select the label, and click Attributes Inspector.
Under Label you should see "Lines 0" like in the screenshot below:
Also, make sure you are handling the excess of characters the way you want - below is an example of the settings to wrap the text to a new line:
You need to calculate your UILabel height and use it as cell height before the cell drawn.
Try this to calculate the UILabel height UILabel height calculation

Self sizing cell with multiple labels does not show multiline label

I'm having three labels in my static table view cell and the middle label should be a multiline one.
I'm setting these two lines in viewDidLoad()
self.tableView.estimatedRowHeight = 130.0
self.tableView.rowHeight = UITableViewAutomaticDimension
The storyboard looks like this
Here are the constraints for each subview
Top label, middle label, bottom label, button
I've also set the number of lines for the middle label to 0. However it only shows one single line, instead of multiple lines. I guess it must have something to do with content hugging or content compression priorities or it's because my I'm using a UITableViewController with static cells.
UPDATE
If I change Vertical Compression Resistance Priority of the middle label to 751 and Vertical Content Hugging Priority to 250, the label shows multilines, but the cell does not get resized, so the top and the bottom label are outside the cell now.
UPDATE 2
I've just created a sample project and it turned out that it works with dynamic cells as expected but not with static cells. You can download the sample project here: https://dl.dropboxusercontent.com/u/67692950/ResizingCell.zip
I cloned your sample project. I think the problem is that you don't need to set UITableViewCell's height.
This is the one simple solution.
・To set Row Height "Default" in Table View Cell.(Unchecked Custom)
In this case, it works.
Download the sample project that I implemented here:
https://www.dropbox.com/s/w8q6ov9qjfxu1l3/ResizingCell.zip?dl=0
But the other way is that you calculate UITableViewCell's height from UILabel's height.
If you customize cell more complicatedly, it is better to isolate cell as a Custom cell.
Firstly, open storyboard, set your tableview row height to be 100, uncheck custom row height for the tableview cell, which value is currently 100.
Secondly, like #DBoyer said, call layoutIfNeeded. If you see "Unable to simultaneously satisfy constraints, Will attempt to recover by breaking constraint X", lower X's priority to 999. I think the warnings may have something to do with that when you get the cell, cell frame is CGRectZero.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)
cell.layoutIfNeeded()
return cell
}
You need to either call layoutIfNeeded on the cell after setting the text of the multiline label or set the labels preferredMaxLayoutWidth
Use aspectRatio constraint for labels. Its puspose is to change width aswell as height according to need.This will help

Swift: Getting a Label in TableView Prototype Cell to display multiple lines (word wrap)

I'm trying to setup a tableview which each cell will have an Image on the left, a Label which overlays the image, and finally a label to the right of the image with long text in which I would like for it wrap to the next line if needed. My tableview row height is set at 65.
I have set the number of lines to 0 and set the line break to work wrap.
I even tried setting parameter programmatically in my CustomTableViewCell class:
self.materialLabel?.numberOfLines = 0
self.materialLabel.sizeToFit()
self.materialLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
I've tried many combinations of setting constraints on my label, but it either doesn't work or affects all objects in the cell with the image and image label out of sync. The alignment constraints are not available to set.
Working with Xcode 6.3.2, Swift 1.2, and iOS 8
Thanks in Advanced!
You can use dynamic cell height ( or self sizing cell).
Basically, you create top, leading, bottom, trailing label's constraints relative to cell's contentView.
and then set
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = someValue
http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift
There are many ways to setup dynamic height for table cell.
If your not not using autolayout, you need to calculate table size programmatically and return using table view delegate method.
If your using autolayout, your life will be very easy. Add constraints to cell, I.e add border, width and height constraints to image. Add only 4 border constraints to image(don't add height constraint). This may not be the exact constraints, but this will give you a idea. Add following code in viewDidload
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = someValue
This should work.
Turns out my label width was too wide. I had to anchor my imageview and the imagelabel and set the width and height before setting the constraints on my label.

Resources