How to Re-Layout UITableViewCell with added Views on Runtime - ios

I have a scenario in my app, in which I have to create a UITableViewCell content in runtime, depending on values I get from network. I'll try to explain what I try to achieve and the issues I am facing. Instead of a specific answer I would like to hear a general solution for this whole problem.
Attempts
I have a UITableView with a custom UITableViewCell which has some container views that could include views depending on runtime values.
UITableViewCell has been designed using storyboard with auto layout enabled.
For the views that would contain dynamic views, I have defined a height constraint to be v.height >= 0. But the height on interface builder is bigger than zero and I would expect cell re-layout after adding views.
The dynamic views are typically rows which are added vertically, but there is a scenario that I'm adding views horizontally.
I have used OAStackView, an alternative to UIStackView for pre-iOS9 devices.
I add my dynamic views on awakeFromNib method of my custom UITableViewCell
I tried to call some methods in hopes they would update my layout. The last one I used [self setNeedsUpdateConstraints]
On my view controller that includes UITableView I tried
myTableView.rowHeight = UITableViewAutomaticDimension;
myTableView.estimatedRowHeight = 300;
And
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Findings and Issues
My UITableViewCell seems to be created and the dynamic views. However it looks like the total height of the cell is exactly the same as the one I defined with storyboard.
View container heights are also the same as I designed them on storyboard, looks like v.height >= 0 is not the only constraint affecting those views (I haven't defined any other constraint regarding to height attribute)
The first view seem to be added nicely, but the other views are quite stretch (I think it's because no place for them)
Can you please help me to find a solution for this general problem? Thank you
Edit: cell image on request

Related

swift uitableview in uitableviewcell with auto layout always height of 0

I have a UITableView defined in a storyboard with a UITableViewCell that contains another UITableView as part of its content with a UITableViewCell defined in it all in a storyboard.
IB image
Both content views are fully specified by auto layout. The nested table however always has a frame height of zero. If I turn on a height for the nested table you can see all of the content so I know it is there; however without the hard coded height its always 0. I've done this before but for whatever reason I am missing something.
The top level table works fine. The nested table properly loads its cells. I've done the trick of
removalTable.estimatedRowHeight = 127
removalTable.rowHeight = UITableViewAutomaticDimension
removalTable.setNeedsLayout()
removalTable.reloadData()
I'm not really new to SO but for whatever reason I can't get my openID to work.
I have seen this error a lot of times.
it is probably because you are not setting good constraints inside the cell you are displaying. What you need to check?
you have an anchor to the top and the bottom at least.
you have a fixed height in one view of your content.
Maybe this post can help you: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
I hope it helps you.

UITableViewCell of mixed xibs and programmatically generated UITableViewCells

I have to integrate a UITableViewCell generated programmatically from code like so:
UITableViewCell *newCell = [[UITableViewCell alloc] initWithFrame: CGRectMake(0,0, screenWidth, 150];
However the rest of the cells in this table view are generated with xibs that rely on autolayout, and so the original programmer only used the estimatedHeightForRow method rather than the heightForRow.
My programmatically generated table view cell is all botched (has the default estimated height of 64 rather than the frame's height of 150) unless I implement heightForRow whereas the existing cells are botched as soon as I do implement heightForRow in addition to estimatedHeightForRow. Is there a way around this conundrum?
Thanks for any advice.
Firstly, you should use UITableViewCell's designated initializer - initWithStyle:reuseIdentifier: instead the UIView's initWithFrame:. However, I don't think that is the cause of your problem as I have tested initWithFrame: and it appears to default to default style and no reuse identifier.
You haven't said what you are doing with the cell once you instantiate it. Are you using the default layout or adding your own custom views? The default layout (with just a line of text) appears to work correctly in my testing, with the cells being sized according to the amount of text in the textLabel.
If you are adding custom views you need to ensure that the contentView has vertical constraints that fully define its height. For example, if you have two UILabels vertically aligned then you will need a vertical constraints such as #"V:|-10-[label1][label2]-10-|". If the constraints are not fully defined then contentView will collapse to zero and your views will appear overlapping the next cell.
To give a little more detail, when using self-sizing cells UITableView does not look at the frame of the returned cell but rather calls the cell's systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:. This results in the Auto Layout engine analyzing the cell's constraints to calculate the appropriate layout size. UITableView then sets the cell's frame according to that size and its position in the table.
I would put an if statement in your height for row method and set the heights to their corresponding cell. It would also be easier if I could see code.

Swift: UITableViewCell size to width of parent UITableView with autolayout enabled

I'm experimenting with autolayout and am running into trouble with UITableViewCell since they're created at runtime. My cells are loaded from a xib from the main ViewController. This xib has View mode set to Aspect Fill.
I've read about different ways to do this online and have yet to get any of them working. What's considered the best way to handle this?
It looks like your constraints aren't set properly, as the cell is shorter than the image's height.
Using AutoLayout and self-sizing cells is the easiest way to handle what you want to do. Once your constraints are setup properly for your custom cell, tableView:cellForRowAtIndexPath: can call dequeueReusableCellWithIdentifier:forIndexPath: and all the subview layout will be handled for you.
See the detailed walkthrough by smileyborg in his answer to Using Auto Layout in UITableView for dynamic cell layouts & variable row heights.
He also provides workarounds for the minor issue with the initial cell width being based on the storyboard cell, instead of the tableView width. I worked around it by setting the cell's initial width to the tableView's width, as Rasputin had suggested.

iOS: UITableViewCell - Cells interrupting/overlaying eachother

I've build a UITableView with different costum cells. One is with a UIImageView and one without. But they are overlaying each other. I've set all constraints.
every cell owns its own section.
screens:
(image and text are samples.)
Does the actual cell height change?
If so, you need to make sure you're returning the correct height with:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return heightOfCell;
}
It looks like you might have the constraints wrong on the cell without the image as it is drawing beyond where the table thinks the height suggests it should end. Hence why it is drawing beyond where the second cell top starts.
Possible issues are:
0) You are returning a height from heightForRowAtIndexPath which is too small. Use auto layout for iOS8 or if suppoting iOS7, you will need to calculate the height.
1) Perhaps your constraints are wrong. Have you pinned the bottom text to the bottom of the cell contentView and the top of the date to the top of the contentView?
2) If using iOS8 auto layout, try adding [self.tableView reloadData]; in viewWillAppear. Sometimes it needs an extra kick to get the layout right, especially if text needs resized. I have no explanation for this other than I had to do this and I've seen it mentioned a few times elsewhere.

UITableViewCell - How to handle dynamic sized content views from Nibs

When I want to have a custom cell, I generally add a UIView subclass to the cell's content view. For the layout of my subviews I use a nib. Then I wire up the nib to my UIView subclass. My issue is how to dynamically size content. Say my view has a lot UILabels inside it. I use layoutSubviews to position all the subviews - but it is only until that is done that I truly know the height of my cell. So currently in tableView:heightForRowAtIndexPath I setup my subview and call layoutIfNeeded so everything is positioned properly. Now I know the height of my cell and return it in the tableView:heightForRowAtIndexPath method. But now when tableView:cellForRowAtIndexPath is called the cell that I am given has a height of 44.0. When I added my subview to it - my subview is outside of its parent's bounds. Then when the cell is later resized in iOS to the height that I said I needed, my content is thrown off because of my autoresizingMask. Just trying to figure out if this is an issue others deal with or if I'm approaching it completely wrong. It just seems backwards that we ask for the height, then create a cell that is not that height.
Unfortunately, this is how UITableViews work: You need to provide the heights before the UITableViewCells are actually rendered.
And yes, everyone has to deal with it. :)
You could create an NSArray, add all your custom contentViews, set their frame according to the expected contentView bounds and then use this array as data source in tableView:heightForRowAtIndexPath: and tableView:cellForRowAtIndexPath:. While this isn't exactly efficient, it works fine for small data sets.
Also, here's a nice tutorial with this topic:
UITableViewCell Dynamic Height (by Matt Long)
A similar question on SO:
How can I do variable height table cells on the iPhone properly?

Resources