iOS8: Autosize table cell that contains inner table - ios

I have a problem with iOS8 autolayout / resizing. In my app, there is one full-screen table with different cells. Those cells are dynamically sized to resize based on their content using
self.tableView.estimatedRowHeight = 44.0
self.tableView.rowHeight = UITableViewAutomaticDimension
(see appcoda or stack overflow, using same set of constraints, eg. top/left/right/bottom for top label and left/right/bottom for bottom label). Resulting in something like this:
So this works great. Now, I need to add an extra cell that has another table embedded in it. This embedded table has dynamic number of rows, should not be scrollable, but rather should resize its containing cell according to self size. But no matter what I do with constraints, I cannot get the containing cell (highlighted in red) to grow (the table Row#0, Row#1, ... has actually 10 items, but only first two are shown).
The idea is to have something similar to native ios maps' detail, where for example Reviews looks like an embedded dynamically sized table:

Related

Is it possible to use self sizing cells within self sizing cells?

I want to have self sizing cells within a tableview with self sizing cells. But on first initialisation some cells are not correct. After a scroll to the bottom and the cells will display again the cell size is correct. In the screenshot you can see that the top 2 cells have a white space at the bottom and the third one doesn't. They should all look like the third one.
This is the issue in my main project.
Screenshot
The problem with automatically sizing cells inside automatically sized cells is a bit tricky because you have to understand how it works. UITableView works with estimates most of the time. It usually does not calculate the contentSize precisely because to calculate it precisely, it has to first instantiate every cell, layout it and then calculate its size.
The precise values are calculated only for cells that are displayed (visible in current scroll frame).
The tricky part is that the inner cells (inside your outer cell) are not displayed until the outer cell is displayed therefore the outer cell does not have size calculated correctly. Also note that UITableView does not automatically update cell heights unless explicitly said to do so.
The solution, if you really have to do this, is to calculate the height of the outer cell correctly before it is displayed and manually set a height constraint.
If you know the height (from data source), it's easy. If you actually need to calculate the height of the inner table, you can do something like this:
// make the table high enough to display all cells
innerTableHeightConstraint.constant = 2000
// reload table
innerTable.reloadData()
// force layout
innerTable.layoutIfNeeded()
// now the contentSize is correctly calculated
innerTableHeightConstraint.constant = innerTable.contentSize.height
The whole concept is tricky and ideally you should prefer using UICollectionView or table sections. When you are using inner table views, there won't be any cell reuse for the inner tables and your performance will suffer.
You should not wrap UITableView into UITableViewCell, try to use UITableView Sections instead to add an extra depth level to your UITableView.

Attach/Stick a UIButton under the UITableView

This illustration shows what i'm trying to do:
The green list is the UITableView where it dynamically adjust it's height based on the number of items inside of it.
Underneath of the UITableView is a button that should follow the UITableView whenever it changes it's height size.
The UIButton should always be beneath the UITableView whatever the size of the UItableView.
I'm currently using autoresizing for UITableView
I have tried to use Autolayout but it seems i can't still find the answer.
i currently have no constraints in the layout.
This boils down to calculating the height of the table view that perfectly fits the cells. Basically you need to measure the size of every cell, then create a height constraint on the table view, and set its constant to the sum of the cells' heights.
Measuring the height of cells is tricky thought. If you only have a few cells (like in your illustrations), you can just instantiate all of them, keep them in an array and use systemLayoutSizeFittingSize to calculate their sizes. If you use multi-line labels, it is also important to set their preferredMaxLayoutWidth to appropriate values.
However, if you have only a few cells (and so cell reuse is not important), stack view is probably a better choice than table view. It's just too tricky to calculate the perfect height of a table view.

Dynamic height of two UITableViews embedded in a single view with Auto Layout

I`m trying to adjust the height of two tableviews embedded in a single viewController. .
This is how it is currently displayed
Current constraints
If possible, I want to adjust the height of each table to avoid the scrolling effect of the table (it is not possible when the total content of the tables is higher than the screen, in that case the height of each table must be the same )
I have manually changed the constraints to show you what behavior I want
Expected behavior 1
Expected behavior 2
I have no idea what constraints I have to modify and what part has to be programmatically
Here is a scenario:
Mapping Data to table.
Get tableview's content size
Set the constraint = height of the content size
Update constraint layout.
In your case, i would like to recommend to use 1 table view with 2 sections.
Hope this help.
The best solution would be not using tableView for the first section as its not a complicated content to be displayed on tableView. Even if you want to use tableView, try this.
Take height constraint of the top tableView. Take outlet of the height constraint in your controller. Then just after you are reloading the tableView, assign the contentSize.height to the constraint and call self.view.layoutIfNeeded(). This will change the height of the tableView to be same as content.
You can do same with bottom tableView.

Can hard coded and self-sizing table cells be intermixed within a tableview?

I'm working on an app that will populate the tableview based on a web service response. So far the two content types I know I will be getting will be data shown in a textview, and also in a collection view. I've begun implementing Ash Furrow's AFCollectionView. The dynamic sizing for text areas is working, however the collection view is scrolling within a cell height that is even less than my estimatedRowHeight (210.0).
Because the collection view table cell is not correctly resizing is it possible to explicitly set the height for the collectionView cell(s), and let any of the text based cells remain dynamic?
Your self sizing cells use auto-layout to determine what height to be, and that's based on the intrinsic content size of the subviews. But, that's not the only way auto-layout can specify the height of a view. You can add a static height constraint to your cells which contain a collection view.

iOS - Can I use xib file for variable height table cell where dynamic content and fixed content are mixed

I'm creating a twitter-like app and I'm using a Table view for the feed. Each table cell is a custom cell. I'm designing those cells using xib file. The cell contains profile picture, comment count and a dynamic message block, etc. There are discussions around how to build variable height table cell:
How can I do variable height table cells on the iPhone properly?
The question is, the dynamic content is in the middle of the cell. Below it is fixed height content. As far as I understand, xib file gives each element fixed X and Y value. Can I stack them together like what "div" would do in?
In IB, in the file inspector (first tab of the left panel), disable "Use autolayout" (if you use a recent version of Xcode)
Then select the label which will have a different height (the proper twitter message) in the size inspector, in the size inspector, set the autosizing properly.
The 4 "things" around describe if the label will keep these dimensions fixed or no (in your case, select the 4) and the 2 arrows in the middle describe if the label will autoresize when its parentView is resized.
Then has rdelmar said, you need to implement the tableView:heightForRowAtIndexPath: method of the tableView delegate
The proper way to do this is by using the table view delegate method tableView:heightForRowAtIndexPath:. How you do it depends on what kind of content you're adding, but somehow, you need to calculate the size of the cell needed based on the data for each row, and return that number. The cell has to be designed in such a way, and with the proper layout constraints, so that when it expands, the part or UI element that you want to expand (like a text view or a multi-line label) expands properly.

Resources