// figures out if the item in the list needs to be redrawn into a different position and does it if the need is there private void InvalidateLayoutIfNecesary() { var newIndexPath = CollectionView.IndexPathForItemAtPoint(CurrentView.Center); var previousIndexPath = SelectedItemIndexPath; if ((newIndexPath == null) || newIndexPath == previousIndexPath) { return; } SelectedItemIndexPath = newIndexPath; DataSource.ItemWillMoveToIndexPath(previousIndexPath, newIndexPath); NSAction action = () => { CollectionView.DeleteItems(new[] { previousIndexPath }); CollectionView.InsertItems(new[] { newIndexPath }); }; UICompletionHandler completion = (bool finished) => { DataSource.ItemDidMoveToIndexPath(previousIndexPath, newIndexPath); }; CollectionView.PerformBatchUpdates(action, completion); }
void VisitsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) { if (args.Action == NotifyCollectionChangedAction.Add || args.Action == NotifyCollectionChangedAction.Remove) { BeginInvokeOnMainThread(() => { topBadge.BadgeNumber = source.Visits.Count; if (args.NewItems != null) { var indexPaths = new List <NSIndexPath>(); for (int i = 0; i < args.NewItems.Count; i++) { indexPaths.Add(NSIndexPath.FromRowSection(args.NewStartingIndex + i, 0)); } CollectionView.InsertItems(indexPaths.ToArray()); } if (args.OldItems != null) { var indexPaths = new List <NSIndexPath>(); for (int i = 0; i < args.OldItems.Count; i++) { indexPaths.Add(NSIndexPath.FromRowSection(args.OldStartingIndex + i, 0)); } CollectionView.DeleteItems(indexPaths.ToArray()); } }); } }
void HandleTapGesture(UITapGestureRecognizer sender) { if (sender.State != UIGestureRecognizerState.Ended) { return; } CGPoint initialPinchPoint = sender.LocationInView(CollectionView); NSIndexPath tappedCellPath = CollectionView.IndexPathForItemAtPoint(initialPinchPoint); if (tappedCellPath != null) { cellCount--; CollectionView.PerformBatchUpdates(delegate { CollectionView.DeleteItems(new NSIndexPath [] { tappedCellPath }); }, null); } else { cellCount++; CollectionView.PerformBatchUpdates(delegate { CollectionView.InsertItems(new NSIndexPath[] { NSIndexPath.FromItemSection(0, 0) }); }, null); } }
private async void DeleteSelectedItems() { var selectedIndeces = CollectionView.GetIndexPathsForSelectedItems(); await ViewModel.DeleteSelectedItemsAsync(); DeselectAllItems(); CollectionView.DeleteItems(selectedIndeces); }
public void RemoveItemView(NSIndexPath indexPath) { if (!IsEditing) { throw new InvalidOperationException("Set IsEditing before calling insert/update/remove"); } removeCalendarItem(indexPath); CollectionView.DeleteItems(new NSIndexPath[] { indexPath }); }
public void DeleteSelected() { var selected = CollectionView.GetIndexPathsForSelectedItems(); var items = selected.Select(i => i.Item).OrderBy(i => i).Reverse(); foreach (var item in items) { collectionData.Remove(collectionData[(int)item]); } CollectionView.DeleteItems(selected); NavigationController.ToolbarHidden = true; }
public void PhotoLibraryDidChange(PHChange changeInstance) { var changes = changeInstance.GetFetchResultChangeDetails(FetchResult); if (changes == null) { return; } DispatchQueue.MainQueue.DispatchSync(() => { // Hang on to the new fetch result. FetchResult = changes.FetchResultAfterChanges; if (changes.HasIncrementalChanges) { // If we have incremental diffs, animate them in the collection view. CollectionView.PerformBatchUpdates(() => { // For indexes to make sense, updates must be in this order: // delete, insert, reload, move var removed = changes.RemovedIndexes; if (removed != null && removed.Count > 0) { CollectionView.DeleteItems(ToNSIndexPaths(removed)); } var inserted = changes.InsertedIndexes; if (inserted != null && inserted.Count > 0) { CollectionView.InsertItems(ToNSIndexPaths(inserted)); } var changed = changes.ChangedIndexes; if (changed != null && changed.Count > 0) { CollectionView.ReloadItems(ToNSIndexPaths(changed)); } changes.EnumerateMoves((fromIndex, toIndex) => { var start = NSIndexPath.FromItemSection((nint)fromIndex, 0); var end = NSIndexPath.FromItemSection((nint)toIndex, 0); CollectionView.MoveItem(start, end); }); }, null); } else { // Reload the collection view if incremental diffs are not available. CollectionView.ReloadData(); } ResetCachedAssets(); }); }
void Tapped() { if (tapRecognizer.State == UIGestureRecognizerState.Ended) { var pinchPoint = tapRecognizer.LocationInView(CollectionView); var tappedCellPath = GetIndexPathsForVisibleItems(pinchPoint); if (tappedCellPath != null) { animals.RemoveAt(tappedCellPath.Row); CollectionView.DeleteItems(new NSIndexPath[] { tappedCellPath }); } } }
protected bool TryUpdateItems(NotifyCollectionChangedEventArgs args) { switch (args.Action) { case NotifyCollectionChangedAction.Add: NSIndexPath[] newIndexPaths = PlatformExtensions.CreateNSIndexPathArray(args.NewStartingIndex, args.NewItems.Count); CollectionView.InsertItems(newIndexPaths); return(true); case NotifyCollectionChangedAction.Remove: foreach (var oldItem in args.OldItems) { ItemDeselected(oldItem); } NSIndexPath[] oldIndexPaths = PlatformExtensions.CreateNSIndexPathArray(args.OldStartingIndex, args.OldItems.Count); CollectionView.DeleteItems(oldIndexPaths); return(true); case NotifyCollectionChangedAction.Move: if (args.NewItems.Count != 1 && args.OldItems.Count != 1) { return(false); } NSIndexPath oldIndexPath = NSIndexPath.FromRowSection(args.OldStartingIndex, 0); NSIndexPath newIndexPath = NSIndexPath.FromRowSection(args.NewStartingIndex, 0); CollectionView.MoveItem(oldIndexPath, newIndexPath); return(true); case NotifyCollectionChangedAction.Replace: if (args.NewItems.Count != args.OldItems.Count) { return(false); } NSIndexPath indexPath = NSIndexPath.FromRowSection(args.NewStartingIndex, 0); CollectionView.ReloadItems(new[] { indexPath }); return(true); default: return(false); } }
/// <summary> /// Moves an item (photo) in this collection view from one index path to another index path. /// </summary> void Reorder(IUICollectionViewDropItem item, NSIndexPath destinationIndexPath, IUICollectionViewDropCoordinator coordinator) { var sourceIndexPath = item?.SourceIndexPath; if (CollectionView is null || album is null || sourceIndexPath is null) { return; } // Perform batch updates to update the photo library backing store and perform the delete & insert on the collection view. CollectionView.PerformBatchUpdates(() => { UpdatePhotoLibrary((photoLibrary) => { photoLibrary.MovePhoto(album, (int)sourceIndexPath.Item, (int)destinationIndexPath.Item); }); CollectionView.DeleteItems(new NSIndexPath[] { sourceIndexPath }); CollectionView.InsertItems(new NSIndexPath[] { destinationIndexPath }); }, (finished) => { }); coordinator.DropItemToItem(item.DragItem, destinationIndexPath); }
private async Task CollectionChangedOnCollectionChangedAsync(NotifyCollectionChangedEventArgs args, Task existingTask, IEnumerable itemsSource) { _logger?.LogTrace( "CollectionChanged received action:{action} newItems:{newItemsCount} oldItems:{oldItemsCount} itemsSourceCount:{itemsSourceCount}", args.Action, args.NewItems?.Count ?? 0, args.OldItems?.Count ?? 0, itemsSource.Count()); await existingTask; _logger?.LogTrace("CollectionChanged starting action:{action}", args.Action); itemsSourceBeforeAnimation = itemsSource; if (args.NewItems?.Count > MaxAnimatedItems || args.OldItems?.Count > MaxAnimatedItems) { //No animation change await CollectionView.PerformBatchUpdatesAsync(() => { }); ReloadData(); } else if (args.Action == NotifyCollectionChangedAction.Move) { await CollectionView.PerformBatchUpdatesAsync(() => { if (args.NewItems.Count != 1 && args.OldItems.Count != 1) { _logger?.LogTrace("CollectionChanged {action} action called with more than one movement. All data will be reloaded", args.Action); CollectionView.ReloadData(); return; } var oldIndexPath = NSIndexPath.FromRowSection(args.OldStartingIndex, 0); var newIndexPath = NSIndexPath.FromRowSection(args.NewStartingIndex, 0); CollectionView.MoveItem(oldIndexPath, newIndexPath); }); } else if (args.Action == NotifyCollectionChangedAction.Remove) { await CollectionView.PerformBatchUpdatesAsync(() => { int oldStartingIndex = args.OldStartingIndex; var indexPaths = new NSIndexPath[args.OldItems.Count]; for (int index = 0; index < indexPaths.Length; ++index) { indexPaths[index] = NSIndexPath.FromRowSection(oldStartingIndex + index, 0); } CollectionView.DeleteItems(indexPaths); }); } else if (args.Action == NotifyCollectionChangedAction.Add) { await CollectionView.PerformBatchUpdatesAsync(() => { int newStartingIndex = args.NewStartingIndex; var indexPaths = new NSIndexPath[args.NewItems.Count]; for (int index = 0; index < indexPaths.Length; ++index) { indexPaths[index] = NSIndexPath.FromRowSection(newStartingIndex + index, 0); } CollectionView.InsertItems(indexPaths); }); } else { await CollectionView.PerformBatchUpdatesAsync(() => { }); ReloadData(); } itemsSourceBeforeAnimation = null; _logger?.LogTrace("CollectionChanged done action:{action} newItems:{newItemsCount} oldItems:{oldItemsCount}", args.Action, args.NewItems?.Count ?? 0, args.OldItems?.Count ?? 0); }
private async Task CollectionChangedOnCollectionChangedAsync(NotifyCollectionChangedEventArgs args, Task existingTask, IEnumerable itemsSource) { await existingTask; itemsSourceBeforeAnimation = itemsSource; if (args.NewItems?.Count > MaxAnimatedItems || args.OldItems?.Count > MaxAnimatedItems) { //No animation change await CollectionView.PerformBatchUpdatesAsync(() => { }); ReloadData(); } else if (args.Action == NotifyCollectionChangedAction.Move) { await CollectionView.PerformBatchUpdatesAsync(() => { var oldCount = args.OldItems.Count; var newCount = args.NewItems.Count; var indexes = new NSIndexPath[oldCount + newCount]; var startIndex = args.OldStartingIndex; for (var i = 0; i < oldCount; i++) { indexes[i] = NSIndexPath.FromRowSection(startIndex + i, 0); } startIndex = args.NewStartingIndex; for (var i = oldCount; i < oldCount + newCount; i++) { indexes[i] = NSIndexPath.FromRowSection(startIndex + i, 0); } CollectionView.ReloadItems(indexes); }); } else if (args.Action == NotifyCollectionChangedAction.Remove) { await CollectionView.PerformBatchUpdatesAsync(() => { int oldStartingIndex = args.OldStartingIndex; var indexPaths = new NSIndexPath[args.OldItems.Count]; for (int index = 0; index < indexPaths.Length; ++index) { indexPaths[index] = NSIndexPath.FromRowSection(oldStartingIndex + index, 0); } CollectionView.DeleteItems(indexPaths); }); } else if (args.Action == NotifyCollectionChangedAction.Add) { await CollectionView.PerformBatchUpdatesAsync(() => { int newStartingIndex = args.NewStartingIndex; var indexPaths = new NSIndexPath[args.NewItems.Count]; for (int index = 0; index < indexPaths.Length; ++index) { indexPaths[index] = NSIndexPath.FromRowSection(newStartingIndex + index, 0); } CollectionView.InsertItems(indexPaths); }); } else { await CollectionView.PerformBatchUpdatesAsync(() => { }); ReloadData(); } itemsSourceBeforeAnimation = null; }
internal void DeleteItems(IEnumerable <int> positions) { var indices = positions.Select(o => NSIndexPath.FromRowSection(o, 0)).ToArray(); CollectionView.DeleteItems(indices); }
protected override void CollectionChangedOnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) { if (args.Action == NotifyCollectionChangedAction.Remove) { try { CollectionView.PerformBatchUpdates(() => { var startIndex = args.OldStartingIndex; var indexes = new NSIndexPath[args.OldItems.Count]; for (var i = 0; i < indexes.Length; i++) { indexes[i] = NSIndexPath.FromRowSection(startIndex + i, 0); } CollectionView.DeleteItems(indexes); }, ok => { }); } catch { CollectionView.PerformBatchUpdates(() => { }, animationsCompleted => { ReloadData(); }); } } else if (args.Action == NotifyCollectionChangedAction.Add) { try { if (args.NewItems.Count == 1 && (args.NewItems[0] is IList newItems)) { CollectionView.PerformBatchUpdates(() => { if (newItems != null) { var indexes = new NSIndexPath[newItems.Count]; var startIndex = ItemsSource == null ? 0 : ItemsSource.Count() - newItems.Count; for (var i = 0; i < indexes.Length; i++) { indexes[i] = NSIndexPath.FromRowSection(startIndex + i, 0); } CollectionView.InsertItems(indexes); } }, ok => { }); } else if (args.NewItems.Count > 1 && !(args.NewItems[0] is IList)) { CollectionView.PerformBatchUpdates(() => { var indexes = new NSIndexPath[args.NewItems.Count]; var startIndex = ItemsSource == null ? 0 : ItemsSource.Count() - args.NewItems.Count; for (var i = 0; i < indexes.Length; i++) { indexes[i] = NSIndexPath.FromRowSection(startIndex + i, 0); } CollectionView.InsertItems(indexes); }, ok => { }); } else { base.CollectionChangedOnCollectionChanged(sender, args); } } catch { CollectionView.PerformBatchUpdates(() => { }, animationsCompleted => { ReloadData(); }); } } else if (args.Action == NotifyCollectionChangedAction.Move) { CollectionView.PerformBatchUpdates(() => { var oldCount = args.OldItems.Count; var newCount = args.NewItems.Count; var indexes = new List <NSIndexPath>(); var startIndex = (int)Math.Min(args.OldStartingIndex, args.NewStartingIndex); var endIndex = Math.Max(args.OldStartingIndex, args.NewStartingIndex); for (var i = startIndex; i <= endIndex; i++) { indexes.Add(NSIndexPath.FromRowSection(i, 0)); } CollectionView.ReloadItems(indexes.ToArray()); }, ok => { }); } else { base.CollectionChangedOnCollectionChanged(sender, args); } }