void UpdateCachedAssets() { // Update only if the view is visible. bool isViewVisible = IsViewLoaded && View.Window != null; if (!isViewVisible) { return; } // The preheat window is twice the height of the visible rect. var visibleRect = new CGRect(CollectionView.ContentOffset, CollectionView.Bounds.Size); var preheatRect = visibleRect.Inset(0f, -0.5f * visibleRect.Height); // Update only if the visible area is significantly different from the last preheated area. nfloat delta = NMath.Abs(preheatRect.GetMidY() - previousPreheatRect.GetMidY()); if (delta <= CollectionView.Bounds.Height / 3f) { return; } // Compute the assets to start caching and to stop caching. var rects = ComputeDifferenceBetweenRect(previousPreheatRect, preheatRect); var addedAssets = rects.added .SelectMany(rect => CollectionView.GetIndexPaths(rect)) .Select(indexPath => FetchResult.ObjectAt(indexPath.Item)) .Cast <PHAsset> () .ToArray(); var removedAssets = rects.removed .SelectMany(rect => CollectionView.GetIndexPaths(rect)) .Select(indexPath => FetchResult.ObjectAt(indexPath.Item)) .Cast <PHAsset> () .ToArray(); // Update the assets the PHCachingImageManager is caching. imageManager.StartCaching(addedAssets, thumbnailSize, PHImageContentMode.AspectFill, null); imageManager.StopCaching(removedAssets, thumbnailSize, PHImageContentMode.AspectFill, null); // Store the preheat rect to compare against in the future. previousPreheatRect = preheatRect; }