我正在使用UICollectionView来存储图片,我可以通过覆盖CanMove
和MoveItem
重新排序。
但是当单元格大小很大时,UICollection中的项目只会重新排序,如果单元格大小大约为106高度和宽度,那么如果它们的尺寸较小,则可以重新排序,它们不能重新排序。
查看:
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;
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时,正在调用CanMove
中的MoveItem
和PostImageColectionSource
并正在重新排序项目。但是,如果GetPostCellSize
的宽度和高度大约为50或70,即使手势已激活,CanMove
中的MoveItem
和PostImageColectionSource
也未被调用,因此无法移动
任何人都希望我在UICollectionView中重新排序图像,当单元格大小很小时,宽度和高度都是70左右。
谢谢。
我正在标记swift和objective-C,因为这个问题一般与IOS有关,而不是xamarin特定的
答案 0 :(得分:1)
这里的主要问题是您需要将集合视图传递给gesture.LocationInView(View)调用而不是主视图。在UILongPressGestureRecognizer中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
,这是UICollectionViewDelegate
和UICollectionViewDataSource
在一个类中的组合,但被分配到集合视图的DataSource
属性。所有这些意味着虽然您可以在UICollectionViewDelegate
中实现PostImageColectionSource
的方法,但是不会在该类上调用委托方法,因为集合视图的Delegate
属性设置为{{ 1}},最终来自PostImageFlowLayout
来自UICollectionViewDelegate
。