How to make UICollectionViewCell still live few points outside UICollectionView?

Hi, How to keep Cells in UICollectionView live, still not destroyed on some distance outside from UICollectionView when it's not visible already?


I have 2 reasons if it can help:


  1. Shadow disappear once Cell is outside View
  2. I have animation of custom FlowLayout (zooming out) and it's not perfectly like expected, cell animates from edge, not from few points outside as expected (because animation starts when side Cell was not dequeued yet)


So, as for now, UICollectionViewCell is being destroyed once it's not visible. I need it to be destroyed only when it goes for example by 50 points away from the UICollectionView. I need only original cells, not any kind of it's snapshots/copies.


Thanks.

Replies

I did not test but I would try to prefetch cells



Prefetching Collection View Cells and Data


UICollectionView
provides two prefetching techniques you can use to improve responsiveness:
  • Cell prefetching prepares cells in advance of the time they are required. When a collection view requires a large number of cells simultaneously—for example, a new row of cells in grid layout—the cells are requested earlier than the time required for display. Cell rendering is therefore spread across multiple layout passes, resulting in a smoother scrolling experience. Cell prefetching is enabled by default.
  • Data prefetching provides a mechanism whereby you are notified of the data requirements of a collection view in advance of the requests for cells. This is useful if the content of your cells relies on an expensive data loading process, such as a network request. Assign an object that conforms to the
    UICollectionViewDataSourcePrefetching
    protocol to the
    prefetchDataSource
    property to receive notifications of when to prefetch data for cells.
var isPrefetchingEnabled: Bool

Denotes whether cell and data prefetching are enabled.


var prefetchDataSource: UICollectionViewDataSourcePrefetching?

The object that acts as the prefetching data source for the collection view, receiving notifications of upcoming cell data requirements.


Thanks but that's not what I actually need. Prefetching will help to set the cell parameters, but it will not put cell view into layout mechanism. I am testing this with a dummy cell with only one label inside, so it's super lightweight and prefetching will do nothing here.


Anyway. The point is: Cell does not exist when it's outside of UICollectionView and being created when it's touching CollectionView border. But I need it to be alive when it's 50 points away from CollectionView. That's not about prefetching time. I need Cell to participate in layout mechanism when it's 50points outside of CollectionView.

Too bad.


So, you could try to subclass UICollectionViewLayout


The +50 should probably be done in

func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?

This method returns layout attributes for all cells and supplementary views, which intersect the specified rectangle.


So, try to increase the rectangle beyond frame.


See details:

h ttps://medium.com/@tigraniskandaryan/custom-collection-view-layout-its-not-that-hard-to-create-6a73bcb8fb6e


Hope that may help.

I've created custom UICollectionViewLayout subclass already, it's managing carousel))) The problem is that rect is input parameter, and I guess no chance to affect it... It works great when I am scrolling. But when I launch UIView.animate and animating my custom parameters on CarouselCollectionViewLayout (scaleRate actually), it animates perfectly on zoom in (as all cells was visible at animation start), but on zoom out, starting point is one fulscreen cell and 2 side cells does not exist yet (it will on the end animation point).

Also collectionView's shadow disappear near disappeared cell. Cell is not visible but some shadow should be still visible.


Or maybe I misunderstood your answer and you know how to extend that rect that will pass into layoutAttributesForElements(in rect: CGRect)?

I have not used layoutAttributesForElements ever, so I may be wrong.


But this is a method you can call yourself.

So idea would be to call before you do the problematic animation, passing a rect a bit larger than visible.


But once again, I may be making wrong assumptions on the use of layoutAttributesForElements.

Yes, I call that method already, and rect is being passed by system and I guess represents collectionView bounds, I canot just modify it, I receive it as a parameter. Anyway, I've tried to pass larger rect to super method. No any difference.


The problem is — Cell view just disappear and not managing at all when it became not visible inside collectionView. No difference if I will manage it by layoutAttributesForElements, that cells outside just not exist. And UICollectionViewLayoutAttributes returned only for 1 cell when zoomed in because only one reusable cell keep dequeued, other was destroyed right when they became invisible(((

Could you post a demo project somewhere or give an email address to share code ?

If the problem is that items (cells) are destroyed and recreated:

- could you keep the state of items somewhere ?

- or keep the items themsselves in an array and call them back in itemsAtRow ?


Otherwise, if that's really important for your app, you should use a Technical support ticket to ask Apple.


Of course, that will be interesting to get any answer here.

The problem is not about destroying the content of cells, saving all cell in array will not help.

The problem is cell itself is being destroyed. I can save cells but it works like reusing cells and only cells visible inside UICollectionView bounds exist. If I will save cell in array, cell view will be destroyed anyway, shadow will disappear, no point to save it. Once cell goes outside the screen, boom and it does not exist.


My code is over complicated for just sample, better to show this animation, so you can understand the problem

https://i.stack.imgur.com/cbaF9.gif


Just need that shadow to not disappear. Please, do not recommend wrapping view inside larger view, stretching parent collection view etc, that don't work in my case.

Did you ever solve this problem?