Xamarin:UICollection 图像重新排序问题 [英] Xamarin: UICollection Image reorder Issue

查看:33
本文介绍了Xamarin:UICollection 图像重新排序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 UICollectionView 来存储图像,我可以通过覆盖 CanMoveMoveItem 来重新排序.

I am using UICollectionView to store images and I can reorder them by overriding CanMove And MoveItem.

但是 UICollection 中的项目仅在单元格大小较大时才重新排序,例如单元格大小约为 106 的高度和宽度,如果它们的大小较小,则可以重新排序,无法重新排序.

But the items inside the UICollection only reorder when cell size is large like if cell size is around 106 height and width, then they can be reordered if they are smaller in size, they are cannot be reordered.

查看:

        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);
}

UICollectionViewDelegateFlowLayout使用系统;使用 System.Windows.Input;使用 CoreGraphics;使用 UIKit;

UICollectionViewDelegateFlowLayout using System; using System.Windows.Input; using CoreGraphics; using 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 左右时,PostImageCollectionSource 中的 CanMoveMoveItem 正在被调用,项目正在被调用重新排序.但是如果 GetPostCellSize 的宽度和高度大约为 50 或 70,即使手势被激活,PostImageCollectionSource 中的 CanMoveMoveItem 没有被调用,因此无法移动.

When the GetPostCellSize in PostImageFlowLayout has width and height of around 100, the CanMove and MoveItem in PostImageColectionSource are being called and items are being reordered. But if the GetPostCellSize has width and height of around 50 or 70, even though the gestures are activated, CanMove and MoveItem in PostImageColectionSource are not being called hence cannot be moved.

当单元格大小很小(例如宽度和高度为 70 左右)时,任何人都可以希望我重新排序 UICollectionView 中的图像.

Can anyone hope me with reordering the images in UICollectionView when the cell size is small like around width and height of 70.

谢谢.

我正在标记 swift 和 Objective-C,因为这个问题一般与 IOS 相关,而不是特定于 xamarin

I am tagging swift and objective-C as this issue is related to IOS in general and not xamarin specific

推荐答案

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

Main issue here is that you need to pass in the collection view to the gesture.LocationInView(View) call instead of the main View. In ViewDidLoad in the UILongPressGestureRecognizer change:

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.

另一件需要注意但不是什么大问题的是,PostImageCollectionSource 最终派生自 UICollectionViewSource,它是 UICollectionViewDelegate 的组合和 UICollectionViewDataSource 在一个类中,但被分配给集合视图的 DataSource 属性.所有这一切意味着,尽管您可以在 PostImageCollectionSource 中为 UICollectionViewDelegate 实现方法,但不会在该类上调用委托方法,因为 Delegate集合视图设置为 PostImageFlowLayout,它最终通过 UICollectionViewDelegateFlowLayout 派生自 UICollectionViewDelegate.

Another thing to note, but not a huge deal, is that PostImageColectionSource is ultimately derived from UICollectionViewSource, which is a combo of UICollectionViewDelegate and UICollectionViewDataSource in one class, but is being assigned to the DataSource property of the collection view. All this means is that though you can implement methods for UICollectionViewDelegate in PostImageColectionSource the delegate methods will not be called on that class since the Delegate property of the collection view is set to the PostImageFlowLayout, which derives ultimately from UICollectionViewDelegate via UICollectionViewDelegateFlowLayout.

这篇关于Xamarin:UICollection 图像重新排序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆