Oh, I tried playing the video while scrolling before. I did not do it then. When you did this, you probably saw my question about this, since this is most of the same logic? In the end, I started playing the video when the scrolling stopped, but that was a long time ago, and I am no longer working on it.
Now I may have an idea for you.
Before diving into it, I just say: this one works , but I'm not 100% sure if it will work for a video game. You have to find out. I apologize for this, but it can be quite difficult.
It completely depends on your situation with the number of cells, etc., you may be interested to disable cell reuse and just recompile everything.
I have not done this in UICollectionViewCell
, and I don't know what KolorEyes
, but it will probably work for UITableViewCell
and AVPlayer
, although I don't have time or will check it. I will try to explain the logic of what I think.
I did not do any Objective-C
, so I will do it in Swift
, but I hope you understand what I think: First make this class:
class PrecompiledCell{ var cell:UICollectionViewCell? = nil var size:CGSize? = nil
This class is just a wrapper for your cell. Now you must create one instance of PrecompiledCell
for each cell that you will display, I. One for each followerFeed file. You must make a function called precompileCells()
and call it whenever you update your data source ( followerFeed
). This function should traverse all the elements of your follwerFeed
-array and create one cell for each. Like your cellForRowAtIndexPath
, perhaps today.
var followerFeed:[[String:Any]] = [] // Your data. Probably an NSArray with NSDictionaries inside? var precompiledCells:[PrecompiledCell] = [] //Your array of precompiled cells func precompileCells(){ var precompiledCells:[PrecompiledCell] = [] for feed in followerFeed{ //Create the cell let videoCell = UINib(nibName: "MyVideoCell", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! MyVideoCell //Each instance of this cell (MyVideoCell) should already be initialising its very own KolorEyes-player etc., so now you can say this: videoCell.kolorEyesPlayer.setAssetURL(feed["video"]) //Of course, convert String to NSURL etc. first.. let precompiledCell = PrecompiledCell() precompiledCell.cell = videoCell precompiledCell.size = //Find out what size the cell is. Eg by using videoCell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize), or even easier if you have a constant size. precompiledCells.append(precompiledCell) } self.precompiledCells = precompiledCells }
Now it’s important not to do this job twice. The whole idea of this answer is that your regular cellForRowAtIndexPath
(or scrollViewDidScroll
in your case) should not do all this work when using scroll. The reason for the current delay is that the view initializes so many things while scrolling. With these precompiled cells, everything is already initialized before you can start scrolling. So, now remove the initializations and any deviations from your regular delegate methods and do the following:
func collectionView(collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { return self.precompiledCells[indexPath.row].cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return self.precompiledCells[indexPath.row].size }
When scrolling, there is no longer an initialization element, because everything has already been initialized before. The only thing you need to do now is use your old scrollViewDidScroll
function, do the same as you (save the current index, etc.), and just put [player play];
and not other things.
Important thoughts
First, it is really important to call collectionView.reloadData()
after self.precompileCells
. Therefore, this should happen as follows:
self.followerFeed = [] self.precompileCells() self.collectionView.reloadData()
In addition, this implementation will completely disable dequeuing, which is actually bad practice as far as I know. Do not use this if you are loading a huge number of cells. Then try to break it a little.
This implementation may cause a delay in the actual precompilation, but rather than a delay in scrolling.
If you load swap cells (for example, scrolling to the end will load more cells), then you should really improve my code, as it will recompile all cells. Then you should do something like insertPrecompiledCells
-thingy.
Once you have precompiled your cells, each cell can decide for itself whether it should start downloading the video. If they need to download the entire video, just a few seconds after the video starts or download it before you ask it to play at all. Running a partial load can be either asynchronous or a simpler start when scrolling.
I thought when writing this it might be a bad idea to have KolorEyes
-player for each cell. You might want to have one single KolorEyes
-player globally and just pass it to the correct cell - but , you can still compile the cell before setting up the video player, and you can also run the actual video asynchronously (without a player) (depending on what the hell is KolorEyes player, but you'll see that part of him ...)
Again, this is just an idea that might work. I used this for tableViews
with complex cells to dramatically increase the smoothness of scrolling, but in a very controlled way (no more than 30 rows, etc.).
I still have ideas and thoughts about this, but this post is already too long, and I have to go now. Good luck