Dynamically update uicollectionview cell height - ios

I am working on a quite complicated case
I have a nested UICollectionView
The outer UICollectionView A is for vertical scrolling,
and it's the first cell, is UICollectionView B, for horizontal scrolling.
It has been implemented perfectly, but now there is one more requirement
When scrolling the first cell to the second page, there is one more banner appeared on the bottom of the first cell.
Therefore I need to update the height of cell when scrolling.
If I try to call invalid layout when scrolling, it will be very low efficient. Are there any more methods to support it?

Solved.
First after received the data from the server, each cell height will be calculated and [collectionview reload] will be called.
Then after layouting the collectionview, the size for each cell is cached according to the indexpath.
To implement the 'realtime' resizing, the gesture will call a resizing function directing through a delegate, and directly modify the size cache and call [collectionview.layout invalidlayout].
It looks smooth.

Related

Only first collectionViewCell reacts to user interactions

The setup
I have a rather complex view hierarchy which made me do terrible things with tableViews and collectionViews. Right now I'm having a regular grouped TableView with custom TableCells. TableCell itself contains a couple of views and a Collection View. The height of the table cell is calculated based on number of items in the data source. On its creation table cell creates a collection view with a calculated size to fit necessary data.
-- UITableView
---- UITableViewCell
------ UICollectionView
--------- UICollectionViewCell
The problem
I've encountered unusual problem with a custom collectionViewCell. I have a vertical single-column collectionView with dynamic amount of cells. Ideally tapping on the cell should call didSelectItemAt. The cell also has three buttons. Tapping on the button should trigger some action. All of the desired functions work only for a first cell. The rest of the cells are not responsive to any actions.
Things that look strange
By default the scrolling of a collectionView inside of the tableViewCell is disabled because it basically fits all the content based on calculated height and doesn't require scrolling. (Also I don't want it to interfere with tableView scrolling logic).
First
I've tried to hardcode some value for the height of collectionView and enable scrolling. What happened is a mystery for me.
Let's say that calculated height required for the collectionView to show all the content without scrolling is 740. When I manually set it to be 280 (this is enough for exactly 2 cells to fit) and enabled scrolling my first cell were still working, but also when I scrolled collection just a little bit my second cell started to act normally as well. When I scrolled back to the top of the collectionView it was disabled once again.
So it looks like when the scrolling is enabled and will actually occur because of insufficient height to fit the content, cells behave as they should. As soon as I set height of the collectionView to be enough to fit its content, things go wrong.
Second
In some cases I can actually tap on the second cell and it will call the delegate. But the weird thing is it works when I tap in the top area of the cell, like 10pts from the top. The other areas of the cell are unresponsive so are the rest of the cells in the collection.
The working delegates and buttons with enabled scrolling forces to think that this has nothing to do with delayed or canceled touches. The frame for collectionView and height of the table cell are calculated properly as well.
xCode 8.3, iOS9+
As it turned out when I was creating my tableViewCell, I hardcoded the height of the collection to value of 214. The reason for that is very simple. I create a cell programmatically and with tableViewCells created programmatically the height of the cell is always 44. When you override init(style: UITableViewCellStyle, reuseIdentifier: String?)
You need to either hardcore the height, or update it in cellForRowAtIndexPath. Even though I updated collection frame when it was filled with data, the container view of this collection wasn't updated resulting in some sort of clipping area for user interactions.

How to scroll the UICollectionview from particular cell

I have a collection view. I need to scroll only cell4, cell5, cell 6 so on. First two cells are remain same. Is is possible using only UICollectionview. How to achieve this.
FYI: the height of the cell is more than the screen height.
One of options would be to subclass UICollectionViewLayout and update frames in attributes of first three cells every time when scroll offset changes. So the cells would look static.

How to get height of UITableView placed in another UITableView in Cell as childViewController

I'm struggling with wired kind of problem. I have UITableView with one cell. This cell is only holding containerView with childViewController (second tableView). My problem is that, first tableView(parent) must have UITableViewAutomaticDimension row height but it doesn't work (It dosen't know correct size of that cell with second tableView).
How to get correct size of second tableView) ?
Second tableView (inside Cell) have scrollingEnabled turned off (tableView.scrollEnabled = false), first tableView must have correct size of second tableView in order to provide correct scrolling experience.
Since a UITableView inherits from UIScrollView you can use the contentSize property to get this information. This is how the scrollbar works on the side.
I have done a similar thing before (long ago), so the following is somewhat hazy/ irrelevant/ unessecary. There might be some gotchas with unknown/unrendered cell heights in the embedded tableview. I rememeber having to set the tableview height to a large number (forcing all cells to render) fetching the contentSize then resetting the tableview height to the contentSize.height.
Are you shure you really need second table view? If you have just one cell probably you don't need it. I recommend you to calculate table view height as the summ of it's cells heights. If cells of embedded table view have constant height it could be simple. In other case you also could calculate cells height.

UICollectionViewCells disappear when going out of UICollectionView frame

Consider the following:
I have a UICollectionView with a size of 400x400. This UICollectionView has 5 UICollectionViewCells which also have a size of 400x400.
Clip to bounds is set to false so that my UICollectionViewCells will be visible (this does not work, I can only see 1). I want this so I can use paging. When I start scrolling there are 2 cells, but when the scrolling snaps, the previous cell disappears and I can only see 1 cell.
I use dequeueReusableCellWithReuseIdentifier to retrieve cells to fill the collectionview. Can this be part of the problem?
How can I display the UICollectViewCells that are out of the collection view's frame?
You can't. What you describe for a problem is actually a feature of UICollectionView and UITableView. They reuse the cells that are not visible for performance and memory reasons. You might think of another approach like UICollectionView with custom layout if that would be possible for your requirement or directly use UIScrollView with paging and you rearrange all the views while is scrolling.

Monotouch: Force UITableView to recalculate height of each cell without reloading data

I have a custom cell created using OwnerDrawnElement with autoresizeable UITextView in it.
When text changed there should be appropriate layout redraw and cell height recalculation.
The problem is how to preserve keyboard opened.
There is a method inside UITableView - ReloadRows which actually helped me in some fashion.
I can't call it for my cell because it is the first responder and can't I cant resign it.
But when I call it for another cell my cell is getting resized as I wanted but I have unnecessary another cell redraw.
So I wonder what method is called to relayout UITableView NOT reload data?!
The same method is probable called when you scroll up and down, cells become visible and height is recalculated.
I've tried standard SetNeedsDisplay(), SetNeedsLayout(), ReloadInputViews(), LayoutSubviews(), but it didn't do the same. Maybe I need use them somehow differently. I've tried to call them for cell and whole tableview objects.
I've looked into ReloadRows method and found out that it calls some API stuff:
Messaging.void_objc_msgSendSuper_IntPtr_int(base.SuperHandle, UITableView.selReloadRowsAtIndexPathsWithRowAnimation_, nSArray.Handle, (int)withRowAnimation);
So it doesn't what method forces tableview to recalculate height of each cell without reloading data either.
Can you help me with that?
Try to update cells frames, then call UITableView's empty update block:
tableView.BeginUpdates();
tableView.EndUpdates();

Resources