Xamarin:UICollection图像重新sorting问题

我正在使用UICollectionView来存储图像,我可以通过重写CanMoveMoveItem来重新排列它们。

但是UICollection里面的项目只有在单元大小很大的时候才会重新sorting,就像单元格大小在106左右的高度和宽度一样,如果它们的大小较小,它们可以重新sorting,它们不能被重新sorting。

视图:

  public override void ViewDidLoad() { base.ViewDidLoad(); //ImageCv is the name of UiCollectionView var collectionLayout = new PostImageFlowLayout(3, 0.85f); var allCollectionSource = new PostImageColectionSource(ImageCv, (ViewModel as NewPostDetailViewModel)); ImageCv.RegisterNibForCell(PostImageCell.Nib, PostImageCell.Key); ImageCv.RegisterClassForSupplementaryView(typeof(CollectionHeader), UICollectionElementKindSection.Header, new NSString("headerId")); ImageCv.BackgroundColor = UIColor.Clear; ImageCv.Hidden = false; ImageCv.DataSource = allCollectionSource; ImageCv.Delegate = collectionLayout; var longPressGesture = new UILongPressGestureRecognizer(gesture => { // Take action based on state switch (gesture.State) { case UIGestureRecognizerState.Began: var selectedIndexPath = ImageCv.IndexPathForItemAtPoint(gesture.LocationInView(View)); if (selectedIndexPath != null) ImageCv.BeginInteractiveMovementForItem(selectedIndexPath); Debug.WriteLine("Gesture Recognition: Activated"); break; case UIGestureRecognizerState.Changed: ImageCv.UpdateInteractiveMovement(gesture.LocationInView(View)); Debug.WriteLine("Gesture activated: Item location is changed"); break; case UIGestureRecognizerState.Ended: ImageCv.EndInteractiveMovement(); Debug.WriteLine("Gesture activation: complete"); break; default: ImageCv.CancelInteractiveMovement(); Debug.WriteLine("Gesture activation: Terminate"); break; } }); // Add the custom recognizer to the collection view ImageCv.AddGestureRecognizer(longPressGesture); } 

使用System的UICollectionViewDelegateFlowLayout; 使用System.Windows.Input; 使用CoreGraphics; 使用UIKit;

 namespace Sources.CollectionSources { public class PostImageFlowLayout : UICollectionViewDelegateFlowLayout { private float headerHeight; private int noOfItems; private bool isLoading; public PostImageFlowLayout(int noOfItems, float headerHeight = 0f) { this.noOfItems = noOfItems; this.headerHeight = headerHeight; } public override CGSize GetSizeForItem(UICollectionView collectionView, UICollectionViewLayout layout, Foundation.NSIndexPath indexPath) { return GetPostCellSize(); } public override CGSize GetReferenceSizeForHeader(UICollectionView collectionView, UICollectionViewLayout layout, nint section) { return new CGSize(collectionView.Frame.Width, headerHeight); } public override UIEdgeInsets GetInsetForSection(UICollectionView collectionView, UICollectionViewLayout layout, nint section) { return new UIEdgeInsets(0, 0, 0, 0); } private CGSize GetPostCellSize() { var relativeWidth = (UIScreen.MainScreen.Bounds.Width - 2) / this.noOfItems; return new CGSize(relativeWidth, relativeWidth); //return new CGSize(55, 55); } } } 

资源

 public class PostImageColectionSource : MvxCollectionViewSource { private NewPostDetailViewModel newPostDetailViewModel; private string type; static NSString animalCellId = new NSString("PostImageCell"); static NSString headerId = new NSString("Header"); List<IAnimal> animals; protected override NSString DefaultCellIdentifier { get { return PostImageCell.Key; } } public override System.Collections.IEnumerable ItemsSource { get { return base.ItemsSource; } set { base.ItemsSource = value; CollectionView.ReloadData(); } } public PostImageColectionSource(UICollectionView collectionView, NewPostDetailViewModel newPostDetailViewModel) : base(collectionView) { this.newPostDetailViewModel = newPostDetailViewModel; animals = new List<IAnimal>(); for (int i = 0; i < 20; i++) { animals.Add(new Monkey(i)); } } public override nint NumberOfSections(UICollectionView collectionView) { return 1; } public override nint GetItemsCount(UICollectionView collectionView, nint section) { return 5;// animals.Count; } public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath) { var cell = (PostImageCell)collectionView.DequeueReusableCell(animalCellId, indexPath); var animal = animals[indexPath.Row]; cell.Result(indexPath.Row); return cell; } public override bool CanMoveItem(UICollectionView collectionView, NSIndexPath indexPath) { Debug.WriteLine("Ready to move images"); //System.Diagnostics.Debug.WriteLine("Checking if it can move the item"); return true; } public override void MoveItem(UICollectionView collectionView, NSIndexPath sourceIndexPath, NSIndexPath destinationIndexPath) { //base.MoveItem(collectionView, sourceIndexPath, destinationIndexPath); Debug.WriteLine("Start moving images to reorder"); var item = animals[(int)sourceIndexPath.Item]; animals.RemoveAt((int)sourceIndexPath.Item); animals.Insert((int)destinationIndexPath.Item, item); } } 

当PostImageFlowLayout中的GetPostCellSize的宽度和高度大约为100时, PostImageColectionSource中的CanMoveMoveItem被调用,并且项目正在被重新sorting。 但是,如果GetPostCellSize宽度和高度在50或70左右,即使手势被激活, PostImageColectionSource中的CanMoveMoveItem也不会被调用,因此无法移动。

任何人都可以希望我重新sortingUICollectionView中的图像,当单元格的大小是像70左右的宽度和高度。

谢谢。

我正在迅速和客观地标记C,因为这个问题一般与IOS相关,而不是xamarin特定的

这里的主要问题是,您需要将集合视图传递给gesture.LocationInView(View)调用,而不是主视图。 在ViewDidLoad的ViewDidLoad中更改:

 var selectedIndexPath = ImageCv.IndexPathForItemAtPoint(gesture.LocationInView(View)); 

 ImageCv.UpdateInteractiveMovement(gesture.LocationInView(View)); 

 var selectedIndexPath = ImageCv.IndexPathForItemAtPoint(gesture.LocationInView(ImageCv)); // <-- pass in ImageCV instead of View. (where ImageCV is the collection view) 

 ImageCv.UpdateInteractiveMovement(gesture.LocationInView(ImageCv)); // <-- pass in ImageCV instead of View. 

另外需要注意的是, PostImageColectionSource最终来自UICollectionViewSource ,它是UICollectionViewDelegateUICollectionViewDataSource在一个类中的组合,但是被分配到集合视图的DataSource属性。 所有这一切的意思是,虽然你可以在PostImageColectionSource实现UICollectionViewDelegate方法, UICollectionViewDelegate由于集合视图的Delegate属性被设置为PostImageFlowLayout ,所以最终从UICollectionViewDelegate通过UICollectionViewDelegateFlowLayout派生,委托方法不会被调用。