C# Xamarin - 将目标添加到 UILongPressGestureRecognizer,将其传递给在父 UIViewController 中实现的选择器

C# Xamarin - AddTarget to UILongPressGestureRecognizer passing it a Selector implemented in a parent UIViewController

我很难将事件从 UICollectionViewCell 提升到存在于父 UIViewController 中的处理程序。我正在尝试在 UICollectionViewCell 上检测 LongPress 并在 UIViewController 中触发一个方法 - 将视图放入 "Edit Mode" show/hiding UI 元素并重新加载等. 为此,我的 UIViewController 方法必须调用数据访问层,因此将方法放置在视图层次结构中的这一层是有意义的。

我遵循了 Xamarin and the great advice from Adam Kemp here 的官方文档和技术。

在 Xamarin.IOS 中有很多相互冲突的方法来实现这一点。 las,目前,none 似乎适用于我的情况。我一定是做错了什么!

我有一个继承自 UICollectionViewCell 的自定义 class,它包含一个 private UILongPressGestureRecognizer _recognizer; 和名为 UpdateCell 的方法,如下所示:

    public virtual void UpdateCell(bool CanEdit)
    {
        // Other properties and logic omitted for brevity (no relevance to question)

        this._recognizer = new UILongPressGestureRecognizer();
        this._recognizer.MinimumPressDuration = 0.5;
        this._recognizer.AddTarget(this, new ObjCRuntime.Selector("OnEditModeActivated"));
        this.AddGestureRecognizer(_recognizer);   
    }

我希望长按在我的 UIViewController 中触发以下方法:

        [Export("OnEditModeActivated")]
        public async void OnEditModeActivated()
        {
            if (recognizer.State == UIGestureRecognizerState.Ended)
            {
                this._canEdit = true;
                // call Data Access layer using await 
                _source.Dispose(); // dispose of current UICollectionViewSource object
                _source = new UICollectionViewSource(_data, _canEdit);
                UICollectionView.Source = _source;
            } 
        }

导致问题的行是

`this._recognizer.AddTarget(this, new ObjCRuntime.Selector("OnEditModeActivated:"));`

选择器应该指向父级 UIViewController,它有一个用 [Export("OnEditModeActivated:")] 修饰的 public void OnEditModeActivated

我可以看到编译器 运行 进入 "unrecognized selector" 异常,因为 this(传递给 AddTarget 的第一个参数)显然是 UICollectionViewCell而不是 UIViewController,因此它将寻求通过 UICollectionViewCell(实例)-> OnEditActivated(不存在)来解析 AddTarget

而不是 this 我需要引用父 UIViewController 但我不想通过引用 UpdateCell 方法传递它 - 这意味着通过引用传递许多层因此我的代码变得有点像意大利面条。

如果有人能解释更好的方法,请务必随意。我查看了在 UICollectionViewCell 实例中引发事件但无济于事。此外,我似乎无法在 Xamarin 中获得正确的委托模式!

问题是我使用的层次结构是:UIViewController -> UICollectionView -> UICollectionViewSource -> UICollectionViewCell

我确信可以提出 event/call delegate/call 方法并在视图控制器级别解决...

感谢您抽出宝贵时间帮助解决此问题。

祝一切顺利,

约翰

_recognizer 连接到 ContentView 并在 this 中声明一个方法解决了我的问题。

我改了:

this.AddGestureRecognizer(_recognizer); 

至:

 cell.ContentView.AddGestureRecognizer(_recognizer);

并在装饰有 Export["OnLongPressed:"] which raises an event resolved at theUIViewController` 级别的同一级别创建了一个 OnLongPressed 方法。

顺便说一句,UILongPressGestureRecognizer 引发了多个事件,应该检查长按实际上已经 结束 否则任何进一步的事件/方法调用将发生不止一次,例如:

if(recognizer.State == UIGestureRecognizerState.Ended)
{
    // Raise events call methods here only when the long press ended
}

UILongPressGestureRecognizers 将以多种状态触发,您可以使用 State 属性 documentation here 进行测试。