protected override void Dispose(bool disposing) { if (_disposed) { return; } _disposed = true; if (disposing) { ItemsSource?.Dispose(); CollectionView.Delegate = null; Delegator?.Dispose(); _emptyUIView?.Dispose(); _emptyUIView = null; _emptyViewFormsElement = null; ItemsViewLayout?.Dispose(); CollectionView?.Dispose(); } base.Dispose(disposing); }
public override void ViewWillLayoutSubviews() { base.ViewWillLayoutSubviews(); // We can't set this constraint up on ViewDidLoad, because Forms does other stuff that resizes the view // and we end up with massive layout errors. And View[Will/Did]Appear do not fire for this controller // reliably. So until one of those options is cleared up, we set this flag so that the initial constraints // are set up the first time this method is called. if (!_initialConstraintsSet) { ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size); _initialConstraintsSet = true; } // This update is only relevant if you have a footer view because it's used to place the footer view // based on the ContentSize so we just update the positions if the ContentSize has changed if (_footerUIView != null) { if (IsHorizontal) { if (_footerUIView.Frame.X != ItemsViewLayout.CollectionViewContentSize.Width) { UpdateHeaderFooterPosition(); } } else { if (_footerUIView.Frame.Y != ItemsViewLayout.CollectionViewContentSize.Height) { UpdateHeaderFooterPosition(); } } } }
public void UpdateLayout(ItemsViewLayout layout) { _layout = layout; _layout.GetPrototype = GetPrototype; // If we're updating from a previous layout, we should keep any settings for the SelectableItemsViewController around var selectableItemsViewController = Delegator?.SelectableItemsViewController; Delegator = new UICollectionViewDelegator(_layout, this); CollectionView.Delegate = Delegator; if (CollectionView.CollectionViewLayout != _layout) { // We're updating from a previous layout // Make sure the new layout is sized properly _layout.ConstrainTo(CollectionView.Bounds.Size); CollectionView.SetCollectionViewLayout(_layout, false); // Reload the data so the currently visible cells get laid out according to the new layout CollectionView.ReloadData(); } }
public ItemsViewController(ItemsView itemsView, ItemsViewLayout layout) : base(layout) { ItemsView = itemsView; ItemsSource = CreateItemsViewSource(); UpdateLayout(layout); }
internal UIEdgeInsets GetInsetForSection(ItemsViewLayout itemsViewLayout, UICollectionView collectionView, nint section) { var uIEdgeInsets = ItemsViewLayout.GetInsetForSection(collectionView, itemsViewLayout, section); if (!ItemsView.IsGrouped) { return(uIEdgeInsets); } // If we're grouping, we'll need to inset the sections to maintain the spacing between the // groups and their group headers/footers nfloat spacing = itemsViewLayout.GetMinimumLineSpacingForSection(collectionView, itemsViewLayout, section); var top = uIEdgeInsets.Top; var left = uIEdgeInsets.Left; if (itemsViewLayout.ScrollDirection == UICollectionViewScrollDirection.Horizontal) { left += spacing; } else { top += spacing; } return(new UIEdgeInsets(top, left, uIEdgeInsets.Bottom, uIEdgeInsets.Right)); }
public ItemsViewController(ItemsView itemsView, ItemsViewLayout layout) : base(layout) { _itemsView = itemsView; _itemsSource = ItemsSourceFactory.Create(_itemsView.ItemsSource, CollectionView); UpdateLayout(layout); }
void CheckForEmptySource() { var wasEmpty = _isEmpty; _isEmpty = ItemsSource.ItemCount == 0; if (_isEmpty) { _measurementCells.Clear(); _cellSizeCache.Clear(); } if (wasEmpty != _isEmpty) { UpdateEmptyViewVisibility(_isEmpty); } if (wasEmpty && !_isEmpty) { // If we're going from empty to having stuff, it's possible that we've never actually measured // a prototype cell and our itemSize or estimatedItemSize are wrong/unset // So trigger a constraint update; if we need a measurement, that will make it happen ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size); } }
protected ItemsViewController(TItemsView itemsView, ItemsViewLayout layout) : base(layout) { ItemsView = itemsView; ItemsViewLayout = layout; ItemsView.PropertyChanged += ItemsViewPropertyChanged; }
void EnsureLayoutInitialized() { if (_initialized) { return; } if (!ItemsView.IsVisible) { // If the CollectionView starts out invisible, we'll get a layout pass with a size of 1,1 and everything will // go pear-shaped. So until the first time this CollectionView is visible, we do nothing. return; } _initialized = true; ItemsViewLayout.GetPrototype = GetPrototype; Delegator = CreateDelegator(); CollectionView.Delegate = Delegator; ItemsViewLayout.SetInitialConstraints(CollectionView.Bounds.Size); CollectionView.SetCollectionViewLayout(ItemsViewLayout, false); UpdateEmptyView(); }
protected virtual void UpdateTemplatedCell(TemplatedCell cell, NSIndexPath indexPath) { cell.ContentSizeChanged -= CellContentSizeChanged; cell.LayoutAttributesChanged -= CellLayoutAttributesChanged; var bindingContext = ItemsSource[indexPath]; // If we've already created a cell for this index path (for measurement), re-use the content if (_measurementCells.TryGetValue(bindingContext, out TemplatedCell measurementCell)) { _measurementCells.Remove(bindingContext); measurementCell.ContentSizeChanged -= CellContentSizeChanged; measurementCell.LayoutAttributesChanged -= CellLayoutAttributesChanged; cell.UseContent(measurementCell); } else { cell.Bind(ItemsView.ItemTemplate, ItemsSource[indexPath], ItemsView); } cell.ContentSizeChanged += CellContentSizeChanged; cell.LayoutAttributesChanged += CellLayoutAttributesChanged; ItemsViewLayout.PrepareCellForLayout(cell); }
public virtual void UpdateItemsSource() { _measurementCells.Clear(); ItemsViewLayout?.ClearCellSizeCache(); ItemsSource = CreateItemsViewSource(); CollectionView.ReloadData(); CollectionView.CollectionViewLayout.InvalidateLayout(); }
protected virtual void BoundsSizeChanged() { //We are changing orientation and we need to tell our layout //to update based on new size constrains ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size); //We call ReloadData so our VisibleCells also update their size CollectionView.ReloadData(); }
public CarouselViewController(CarouselView itemsView, ItemsViewLayout layout) : base(itemsView, layout) { _carouselView = itemsView; _layout = layout; Delegator.CarouselViewController = this; CollectionView.AllowsSelection = false; CollectionView.AllowsMultipleSelection = false; }
protected virtual void UpdateTemplatedCell(TemplatedCell cell, NSIndexPath indexPath) { ApplyTemplateAndDataContext(cell, indexPath); if (cell is ItemsViewCell constrainedCell) { ItemsViewLayout.PrepareCellForLayout(constrainedCell); } }
protected void BoundsSizeChanged() { ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size); //We call ReloadData so our VisibleCells also update their size CollectionView.ReloadData(); Carousel.ScrollTo(Carousel.Position, position: Xamarin.Forms.ScrollToPosition.Center, animate: false); }
public CollectionViewController(ItemsView itemsView, ItemsViewLayout layout) : base(layout) { _itemsView = itemsView; _itemsSource = ItemsSourceFactory.Create(_itemsView.ItemsSource, CollectionView); _layout = layout; _layout.GetPrototype = GetPrototype; _layout.UniformSize = false; // todo hartez Link this to ItemsView.ItemSizingStrategy hint }
protected virtual void UpdateLayout() { _layout = SelectLayout(); if (Controller != null) { Controller.UpdateLayout(_layout); } }
protected virtual void UpdateDefaultCell(DefaultCell cell, NSIndexPath indexPath) { cell.Label.Text = ItemsSource[indexPath].ToString(); if (cell is ItemsViewCell constrainedCell) { ItemsViewLayout.PrepareCellForLayout(constrainedCell); } }
protected virtual void UpdateLayout() { _layout = SelectLayout(Element.ItemsLayout, Element.ItemSizingStrategy); if (ItemsViewController != null) { ItemsViewController.UpdateLayout(_layout); } }
public CarouselViewController(CarouselView itemsView, ItemsViewLayout layout) : base(itemsView, layout) { Carousel = itemsView; CollectionView.AllowsSelection = false; CollectionView.AllowsMultipleSelection = false; Carousel.PropertyChanged += CarouselViewPropertyChanged; Carousel.Scrolled += CarouselViewScrolled; _oldViews = new List <View>(); }
public override nfloat GetMinimumLineSpacingForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section) { if (ItemsViewLayout == null) { return(default(nfloat)); } return(ItemsViewLayout.GetMinimumLineSpacingForSection(collectionView, layout, section)); }
protected virtual void UpdateTemplatedCell(TemplatedCell cell, NSIndexPath indexPath) { cell.ContentSizeChanged -= CellContentSizeChanged; cell.Bind(ItemsView, ItemsSource[indexPath]); cell.ContentSizeChanged += CellContentSizeChanged; ItemsViewLayout.PrepareCellForLayout(cell); }
public override UIEdgeInsets GetInsetForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section) { if (ItemsViewLayout == null) { return(default(UIEdgeInsets)); } return(ItemsViewLayout.GetInsetForSection(collectionView, layout, section)); }
public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration) { //We are changing orientation and we need to tell our layout //to update based on new size constrains ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size); //We call ReloadData so our VisibleCells also update their size CollectionView.ReloadData(); base.WillAnimateRotation(toInterfaceOrientation, duration); }
public ItemsViewController(ItemsView itemsView, ItemsViewLayout layout) : base(layout) { _itemsView = itemsView; _itemsSource = ItemsSourceFactory.Create(_itemsView.ItemsSource, CollectionView); // If we already have data, the UICollectionView will have items and we'll be safe to call // ReloadData if the ItemsSource changes in the future (see UpdateItemsSource for more). _safeForReload = _itemsSource?.Count > 0; UpdateLayout(layout); }
void ConstrainToItemsView() { var itemsViewWidth = ItemsView.Width; var itemsViewHeight = ItemsView.Height; if (itemsViewHeight < 0 || itemsViewWidth < 0) { ItemsViewLayout.UpdateConstraints(CollectionView.Bounds.Size); return; } ItemsViewLayout.UpdateConstraints(new CGSize(itemsViewWidth, itemsViewHeight)); }
public override void ViewWillLayoutSubviews() { base.ViewWillLayoutSubviews(); // We can't set this constraint up on ViewDidLoad, because Forms does other stuff that resizes the view // and we end up with massive layout errors. And View[Will/Did]Appear do not fire for this controller // reliably. So until one of those options is cleared up, we set this flag so that the initial constraints // are set up the first time this method is called. if (!_initialConstraintsSet) { ItemsViewLayout.ConstrainTo(CollectionView.Bounds.Size); _initialConstraintsSet = true; } }
protected virtual void CacheCellAttributes(NSIndexPath indexPath, CGSize size) { if (!ItemsSource.IsIndexPathValid(indexPath)) { // The upate might be coming from a cell that's being removed; don't cache it. return; } var item = ItemsSource[indexPath]; if (item != null) { ItemsViewLayout.CacheCellSize(item, size); } }
protected virtual void SetUpNewElement(ItemsView newElement) { if (newElement == null) { return; } _layout = SelectLayout(newElement.ItemsLayout); ItemsViewController = CreateController(newElement, _layout); SetNativeControl(ItemsViewController.View); ItemsViewController.CollectionView.BackgroundColor = UIColor.Clear; ItemsViewController.UpdateEmptyView(); // Listen for ScrollTo requests newElement.ScrollToRequested += ScrollToRequested; }
void SetUpNewElement(CollectionView newElement) { if (newElement == null) { return; } _layout = SelectLayout(newElement.ItemsLayout); _collectionViewController = new CollectionViewController(newElement, _layout); SetNativeControl(_collectionViewController.View); _collectionViewController.CollectionView.BackgroundColor = UIColor.Clear; _collectionViewController.CollectionView.Delegate = _layout; // Listen for ScrollTo requests newElement.ScrollToRequested += ScrollToRequested; }