Created
December 5, 2019 07:20
-
-
Save jsuarezruiz/6cbb45d7a85ec6dfc415ef625cfbf2ee to your computer and use it in GitHub Desktop.
This file contains 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
using System; | |
using CoreGraphics; | |
using Foundation; | |
using UIKit; | |
namespace Xamarin.Forms.Platform.iOS | |
{ | |
public class CarouselViewLayout : ItemsViewLayout | |
{ | |
readonly CarouselView _carouselView; | |
readonly ItemsLayout _itemsLayout; | |
public CarouselViewLayout(ItemsLayout itemsLayout, CarouselView carouselView) : base(itemsLayout) | |
{ | |
_carouselView = carouselView; | |
_itemsLayout = itemsLayout; | |
} | |
public override bool ShouldInvalidateLayoutForBoundsChange(CGRect newBounds) | |
{ | |
return false; | |
} | |
public override void ConstrainTo(CGSize size) | |
{ | |
//TODO: Should we scale the items | |
if (ScrollDirection == UICollectionViewScrollDirection.Horizontal) | |
{ | |
var width = size.Width - _carouselView.PeekAreaInsets.Left - _carouselView.PeekAreaInsets.Right; | |
ItemSize = new CGSize(width, size.Height); | |
} | |
else | |
{ | |
var height = size.Height - _carouselView.PeekAreaInsets.Top - _carouselView.PeekAreaInsets.Bottom; | |
ItemSize = new CGSize(size.Width, height); | |
} | |
} | |
public override CGSize CollectionViewContentSize | |
{ | |
get | |
{ | |
var collectionViewContentSize = base.CollectionViewContentSize; | |
if (ScrollDirection == UICollectionViewScrollDirection.Horizontal) | |
collectionViewContentSize.Width -= (float)(_carouselView.PeekAreaInsets.Left + _carouselView.PeekAreaInsets.Right); | |
else | |
collectionViewContentSize.Height -= (float)(_carouselView.PeekAreaInsets.Top + _carouselView.PeekAreaInsets.Bottom); | |
return collectionViewContentSize; | |
} | |
} | |
public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect(CGRect rect) | |
{ | |
var layoutAttributes = base.LayoutAttributesForElementsInRect(rect); | |
if (layoutAttributes != null) | |
{ | |
foreach (var layoutAttribute in layoutAttributes) | |
{ | |
if (layoutAttribute.RepresentedElementKind == null) | |
{ | |
var index = layoutAttribute.IndexPath; | |
var attributesForItem = LayoutAttributesForItem(index); | |
if (attributesForItem != null) | |
layoutAttribute.Frame = attributesForItem.Frame; | |
} | |
} | |
} | |
return layoutAttributes; | |
} | |
public override UICollectionViewLayoutAttributes LayoutAttributesForItem(NSIndexPath indexPath) | |
{ | |
var currentItemAttributes = base.LayoutAttributesForItem(indexPath); | |
var isFirstItemInSection = indexPath.Item == 0; | |
if (isFirstItemInSection) | |
{ | |
var firstFrame = currentItemAttributes?.Frame ?? CGRect.Empty; | |
if (ScrollDirection == UICollectionViewScrollDirection.Horizontal) | |
{ | |
var firstWidth = firstFrame.Width + _carouselView.PeekAreaInsets.Left - _carouselView.PeekAreaInsets.Right; | |
currentItemAttributes.Frame = new CGRect(firstFrame.X - _carouselView.PeekAreaInsets.Left, firstFrame.Y, firstWidth, firstFrame.Height); | |
} | |
else | |
{ | |
var firstHeight = firstFrame.Height + _carouselView.PeekAreaInsets.Top - _carouselView.PeekAreaInsets.Bottom; | |
currentItemAttributes.Frame = new CGRect(firstFrame.X, firstFrame.Y - _carouselView.PeekAreaInsets.Top, firstFrame.Width, firstHeight); | |
} | |
return currentItemAttributes; | |
} | |
var currentFrame = currentItemAttributes.Frame; | |
if (ScrollDirection == UICollectionViewScrollDirection.Horizontal) | |
currentItemAttributes.Frame = new CGRect(currentFrame.X - _carouselView.PeekAreaInsets.Left, currentFrame.Y, currentFrame.Width, currentFrame.Height); | |
else | |
currentItemAttributes.Frame = new CGRect(currentFrame.X, currentFrame.Y - _carouselView.PeekAreaInsets.Top, currentFrame.Width, currentFrame.Height); | |
return currentItemAttributes; | |
} | |
public override nfloat GetMinimumInteritemSpacingForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section) | |
{ | |
if (_itemsLayout is LinearItemsLayout linearItemsLayout) | |
return (nfloat)linearItemsLayout.ItemSpacing; | |
return base.GetMinimumInteritemSpacingForSection(collectionView, layout, section); | |
} | |
public override UIEdgeInsets GetInsetForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section) | |
{ | |
var insets = base.GetInsetForSection(collectionView, layout, section); | |
var left = insets.Left + (float)_carouselView.PeekAreaInsets.Left; | |
var right = insets.Right + (float)_carouselView.PeekAreaInsets.Right; | |
var top = insets.Top + (float)_carouselView.PeekAreaInsets.Top; | |
var bottom = insets.Bottom + (float)_carouselView.PeekAreaInsets.Bottom; | |
return new UIEdgeInsets(top, left, bottom, right); | |
} | |
internal void UpdateConstraints(CGSize size) | |
{ | |
ConstrainTo(size); | |
UpdateCellConstraints(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment