Can I load a UITableViewCell directly from a xib with a specific size class or trait collection? - ios

I'm trying to do the following in my iOS app:
Embed a UITableView into a parent scroll view; the table view will have its frame expanded to show all its contents (I need to do this because the table view data is a small component of a much larger more complex screen, and I don't want nested scrolling behavior)
I have different layouts for iPhone and iPad, so the cells in this table view are using size classes defined in a table view cell xib.
Since I want the content size of the table view to be accurate, I don't think I can use UITableViewAutomaticDimenstion as the rowheight, so I implement tableView:heightForRowAtIndexPath: and load an instance of my tableview cell from the nib directly and store that view as a property with which I can figure out how tall the cell should be according to autolayout.
My problem stems here; when I load the cell directly from the nib, on iPad the cell uses the constraints and layout in the 'Any' size class as defined in the nib, which is incorrect because the iPad's layout uses the regular width class only in my nib. This causes my table view cell heights to be wrong and too large in my case.
What I need to know is if there's a way to force the trait collection on the cell I load, such that the proper constraints for my views are used on each device type. I can't seem to find anything in the docs that allows for this directly in UIViews, only in UIViewControllers and I'm not keen on holding an offscreen UITableViewCell in a random offscreen UIViewController if i can help it. Any ideas?

After writing this I found this question: Offscreen UITableViewCells (for size calculations) not respecting size class? which seems to ask a similar thing, and the answer in there worked for me (add the offscreen table view cell as a subview of the tableview, or some other view that provides a trait environment). It's not pretty but it seems to work out.

Related

UICollectionViewCell loaded from Xib (Nib) is being covered by storyboard cells as its size is not updating

I'm using a Xib file to hold a UICollectionViewCell item that I do not want to have in a Storyboard. I have the UICollectionView set to calculate its cell sizes automatically. But what I see when the collection view loads is that it's retaining the default 50x50 size for the cell that's being loaded from the Xib file. It's not being updated to the size it is showing up as.
The cell looks correct on screen and at the correct size. But when another cell loads that is contained in the storyboard it's loading on top of the other cell as its being placed 50 points down from the first cell.
The cell outlined in orange is the one being covered up by the one in green. I cannot show a larger portion of this due to work restrictions but I hope this clarifies what's happening.
I've tried to say that the cellNeedsLayout() and layoutIfNeeded() but neither of those make any difference. It's like the actual height that the cell is not being calculated early enough to have the collection view place cells around it correctly.
I've not been able to find a way to preload the Xib so that it already knows how large that needs to be. I am using a subclass of UICollectionView named CollectionCell.
Can anyone point me in the direction to look or suggest a fix for this other than moving what I've done into the Storyboard?

Keeping reuse capabilities of UITableView when it is nested in a UIScrollView

To implement a rather intricate design of a screen in an iOS app, I have a UITableView nested inside of a UIScrollView.
To keep the logic simple, I implemented a method on the UITableView that calculates its entire height, and i use the result of that method and set a constraint on the nested table view, so that the scrolling logic can be solely on the UIScrollView to deal with. (I forward methods such as scrollRectToVisible from the UITableView to the UIScrollView)
While this works great with small data sets, I have recently discovered the the reuse capabilities of the UITableView are not used, because the framework believes the entire UITableView to be visible when I set that height constraint. A simple log method in the cellForRowAtIndexPath method shows all cells get calculated at once.
My question is, is there anything I can do where I would be able to tell the nested UITableView how much of it is actually visible on screen, and to only compute those visible cells?
I basically need to override whatever part of UITableView that is responsible for calculating what cells should be visible on screen.
The table view will think of itself as filling its whole frame with cells. If you limit the height it will limit the cell count visible. Are you using the deque with reuse identifier method (if not see below)
How can I recycle UITableViewCell objects created from a XIB?

Auto Layout in UITableView for dynamic row heights with table view cell from universal storyboard

So far I've had some success in calculating dynamic table cell layouts with auto layout. And so far, I have maintained different storyboards for iPhone and iPad. I would now like to consolidate them into a single storyboard per app. I'm currently stuck at a point where my height calculations do no longer function.
The trouble is apparently that the table view cell as dequeued from the storyboard is still at its fixed storyboard size (relative to a specific device, i.e. iPhone in my case) when the calculation is first required. It will be resized to fit the actual device (iPad in my case) when the table is displayed. But tableView:heightForRowAtIndexPath: is called before that and therefore does its calculation based on the wrong table cell width.
Is there a good way to solve this problem? It seems as if this accepted answer also isn't immune because its instructions also only mention the cell in isolation from its table view.
First, instantiate an offscreen instance of a table view cell, one
instance for each reuse identifier, that is used strictly for height
calculations.

iOS UITableViewCell with scrollView with dynamic content

I am trying to create a table view, in which the table view cells contain a scroll view. The scroll view can contain one or two pages of one image view each. Note that the scroll view will only scroll horizontally, so it will not interfere with the Table View's scroll view that will scroll vertically. Depending on the content, I want the scroll view to be updated with these image views, and set the scroll view content size according to responses I receive from a server, instructing the application what images to display.
In order to do that, I initially thought of creating a custom UITableViewCell subclass, and do all my initialisation of the views inside that.
However, I am just thinking about performance and memory. I know that iOS automatically deallocates already seen views and cells, when it needs to, and that it reuses the old cells when it tries to display something new (by using a reuse identifier). However, each cell will contain a scroll view with content size and subviews that will change in each cell. I want to use a reuse identifier to ensure maximum performance.
Can anyone point me in a way in which I can set up the reuse of a cell like this, and change the contents of each scroll view successfully?
Thanks.
you can make the reuseIdentifier dynamic
e.g. "cell_with_1","cell_with_2","cell_with_x" where x is the number of images
that way equal cells can be reused when sensible (e.g. when the number of images in the view is the same): 'worst case' is no reusing and a tad overhead for trying but in general I'd deem it beneficial :)
*the allocation deallocation and the basic adding of the subviews is expensive.. changing frames or images seems reasonable to me

Getting real width of UITableViewCell's contentView before it displays

I have a grouped table view with custom cells (created programmatically by subclassing, not with IB). To properly position custom cell's subviews (such as labels and text fields), I need to know the current width of the cell's contentView just before the cell displays (taking into account that real cell width in a table view can change (according to screen orientation, modal presentation style, etc.)).
if I override in custom cell class the layoutSubviews method, it works perfectly, but it can be called frequently, thus I have to reposition my subviews every time when it's called, even when there's no need to do that.
Please, recommend me more elegant solution.
The recommended way of doing this is by setting the autoresizingMask of the table cell. If you need to have more control over the layout, you can store the last used view width in a member variable, and only layout the subviews if this differs from the current view width.

Resources