ios - Xamarin iOS : Edit cells of UICollectionView

标签 ios objective-c swift xamarin xamarin.ios

我有一组图像并希望具有“拖动以重新排序”的功能,为此我正在使用 UICollectionView。

如果 View 继承自 UICollectionViewController 那么我可以直接这样做 即,

 public class SimpleCollectionViewController : UICollectionViewController
    {}

通过覆盖 CanMoveCanMoveItem 委托(delegate)。

   public override bool CanMoveItem(UICollectionView collectionView, NSIndexPath indexPath)
            {
                //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);
        System.Diagnostics.Debug.WriteLine("Started moving item");
        var item = animals[(int)sourceIndexPath.Item];
        animals.RemoveAt((int)sourceIndexPath.Item);
        animals.Insert((int)destinationIndexPath.Item, item);
    }

但我当前的 View 不是从 UICollectionViewController 继承的,所以我如何使用“UICollectionViewController”委托(delegate)对 UICollectionView 中的项目重新排序

我添加了 Objective-c 和 swift 标签,因为这个问题与 Xamarin 无关,而是与一般的 iOS 架构相关。

谢谢。

最佳答案

您需要将继承自 UICollectionViewSource [1] 的对象(或实现 IUICollectionViewSource 接口(interface) [2] 的对象)分配给 UICollectionView.Source 属性,例如:

collectionView.Source = new MyUICollectionViewSource(); 

UICollectionViewSource/IUICollectionViewSource 基本上结合了 UICollectionViewDelegate/IUICollectionViewDelegateUICollectionViewDataSource/IUICollectionViewDataSource 到一个类/接口(interface)中。您会注意到 UICollectionView [3] 具有分配 Delegate、DataSource 和 Source 对象的属性。如果您只需要 DataSource 方法,CanMoveItem 和 MoveItem 都是 DataSource 方法,那么只需使用从 UICollectionViewDataSource/IUICollectionViewDataSource 继承的对象并将该对象分配给 DataSource 属性的 Collection View 。

更新:对 UICollectionViewSourceIUICollectionViewSource(或 Delegate 或 DataSource)之间的区别进行了一些澄清。 iOS 中的委托(delegate)和数据源是 Obj-C 协议(protocol)(不确定它们在 swift 中的名称)。 Obj-C 协议(protocol)有点像 C# 接口(interface),但 Obj-C 协议(protocol)可以有必需的和可选的方法,而接口(interface)中的所有方法都必须由继承类实现。所以当 Xamarin 绑定(bind)协议(protocol)时,他们从协议(protocol)中创建一个类,其中包含所有必需和可选的方法,因此您可以只覆盖您需要的方法,但我们也创建了一个仅包含协议(protocol)所需方法的接口(interface),因为我们不想强制你实现协议(protocol)的可选方法。但是,当一个类继承自接口(interface)版本时,例如 IUICollectionViewSource,您将只能覆盖所需的方法,但您仍然可以将可选方法添加到实现该接口(interface)的同一个类中。您可以检查协议(protocol)的类版本,例如 UICollectionViewSource,以查看可选方法的签名,然后在实现接口(interface)版本协议(protocol)的类中实现它们。有关详细信息,请参阅 [4]。

要在实现相关 C# 接口(interface)时实现协议(protocol)的可选方法,您必须使用 [Export()] 属性向 iOS 运行时注册该方法。例如,实现 DataSource 的 CanMoveItem 和 MoveItem 可选方法:

[Export ("collectionView:canMoveItemAtIndexPath:")]
public bool CanMoveItem (UICollectionView collectionView, NSIndexPath indexPath)
{
    // Do stuff
}

[Export ("collectionView:moveItemAtIndexPath:toIndexPath:")]
public void MoveItem (UICollectionView collectionView, NSIndexPath sourceIndexPath, NSIndexPath destinationIndexPath)
{
    // Do stuff
}

找到要与 [Export()] 属性一起使用的 Obj-C 选择器的最简单方法是,右键单击源代码中的 IUICollectionViewDataSource 并选择“转到 Declaration(XS)/Definition(VS)”,程序集浏览器将打开。查找名称与您要实现的方法相匹配的协议(protocol)成员。 Selector 属性是您要在 [Export()] 属性中使用的 Obj-C 选择器。

[1] https://developer.xamarin.com/api/type/MonoTouch.UIKit.UICollectionViewSource/

[2] https://developer.xamarin.com/api/type/MonoTouch.UIKit.IUICollectionViewSource/

[3] https://developer.xamarin.com/api/type/MonoTouch.UIKit.UICollectionView/

[4] https://developer.xamarin.com/guides/ios/application_fundamentals/delegates,_protocols,_and_events/#Protocols

关于ios - Xamarin iOS : Edit cells of UICollectionView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41129579/

相关文章:

iphone - 调用协议(protocol)方法是否通过程序流控制?

objective-c - 从 WKWebView 获取 favicon.co

swift - Swift 中 SKAction.runBlock() 的问题

iphone - 删除 2 个 UIPickerView 组件之间的分隔符

objective-c - AFNetworking 异步数据获取

iphone - 有没有办法在 APNS 推送消息中包含本地时间和时区

swift - 可以使用 Swift 中的实现者定义的功能扩展协议(protocol)吗?

Swift - 在 UITableView 中搜索

ios - XIB 文件消失但应用程序仍然有效

ios - 如何获取本地化 "Purchased"和 "Purchased on My iPhone"播放列表的 MPMediaPlaylist?