Last active
March 16, 2020 10:34
-
-
Save Mogikan/b4bc79f1decf553f4e18c3a6ba387620 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class VerticalGridLayout : UICollectionViewLayout | |
{ | |
public VerticalGridLayout( | |
IGridCellMetricProvider gridMetricProvider, | |
double cellHeight | |
) | |
{ | |
_gridMetricProvider = gridMetricProvider; | |
_cellHeight = cellHeight; | |
} | |
private IGridCellMetricProvider _gridMetricProvider; | |
private double _cellHeight; | |
private Dictionary<NSIndexPath, UICollectionViewLayoutAttributes> attributesCache = new Dictionary<NSIndexPath, UICollectionViewLayoutAttributes>(); | |
private nfloat ContentWidth | |
{ | |
get => CollectionView.Frame.Width - (CollectionView.ContentInset.Left + CollectionView.ContentInset.Right); | |
} | |
private nfloat _contentHeigth; | |
//bounding rect for all items | |
public override CoreGraphics.CGSize CollectionViewContentSize | |
{ | |
get | |
{ | |
var contentHeight = (nfloat)(_gridMetricProvider.GridSize.Height * _cellHeight); | |
return new CoreGraphics.CGSize(ContentWidth,contentHeight); | |
//return base.CollectionViewContentSize; | |
} | |
} | |
//which items to show in scrollview | |
public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(CoreGraphics.CGRect rect) | |
{ | |
return attributesCache.Values.ToArray(); //return base.LayoutAttributesForElementsInRect(rect); | |
} | |
//retrieve layout attributes for specific item | |
public override UICollectionViewLayoutAttributes LayoutAttributesForItem(Foundation.NSIndexPath indexPath) | |
{ | |
double cellWidth = ContentWidth / _gridMetricProvider.GridSize.Width; | |
var gridMetrics = _gridMetricProvider.GridCellInfoForIndexPath(indexPath); | |
var itemAttributes = UICollectionViewLayoutAttributes.CreateForCell(indexPath); | |
double x = cellWidth * gridMetrics.column; | |
double w = cellWidth * gridMetrics.colspan; | |
double y = _cellHeight * gridMetrics.row; | |
double h = _cellHeight * gridMetrics.rowspan; | |
itemAttributes.Frame = new CoreGraphics.CGRect(x, y, w, h); | |
return itemAttributes; | |
} | |
//if collection view size changed or device is rotated | |
public override bool ShouldInvalidateLayoutForBoundsChange(CoreGraphics.CGRect newBounds) | |
{ | |
if (CollectionView == null) | |
return false; | |
return CollectionView.Bounds.Width != newBounds.Width; | |
} | |
//for generating cache | |
public override void PrepareLayout() | |
{ | |
if (attributesCache.Count != 0) return; | |
for (int sectionIndex = 0; sectionIndex < CollectionView.NumberOfSections(); sectionIndex++) | |
{ | |
for (int itemIndex = 0; itemIndex < CollectionView.NumberOfItemsInSection(sectionIndex); itemIndex++) | |
{ | |
NSIndexPath indexPath = NSIndexPath.FromItemSection(itemIndex, sectionIndex); | |
attributesCache.Add(indexPath, LayoutAttributesForItem(indexPath)); | |
} | |
} | |
} | |
//} | |
//clear cache | |
public override void InvalidateLayout() | |
{ | |
attributesCache.Clear(); | |
base.InvalidateLayout(); | |
} | |
} | |
public interface IGridCellMetricProvider | |
{ | |
GridCellInfo GridCellInfoForIndexPath(NSIndexPath path); | |
Size GridSize { get; } | |
} | |
public struct GridCellInfo | |
{ | |
public GridCellInfo(int col,int colspan,int row,int rowspan) | |
{ | |
this.row = row; | |
this.rowspan = rowspan; | |
this.column = col; | |
this.colspan = colspan; | |
} | |
public int column; | |
public int colspan; | |
public int row; | |
public int rowspan; | |
} | |
... | |
CollectionView.SetCollectionViewLayout(new VerticalGridLayout(_dataSource, cellHeight: ApplicationSettings.DefaultCellHeight), false); | |
... | |
class which implements IGridCellMetricProvider | |
... | |
public GridCellInfo GridCellInfoForIndexPath(NSIndexPath path) | |
{ | |
var formControl = GetControlAt(path.Row);//row will be index | |
return new GridCellInfo(formControl.Left, formControl.Width, formControl.Top, formControl.Height); | |
} | |
public Size GridSize => new Size(_form.Width,_form.Height); | |
... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment