C# Xamarin - AddTarget для UILongPressGestureRecognizer, передавая ему селектор, реализованный в родительском UIViewController

У меня возникли трудности с поднятием события из UICollectionViewCell к обработчику, который существует в родительском UIViewController, Я пытаюсь обнаружить LongPress на UICollectionViewCell и запустить метод в UIViewController - перевод представления в "режим редактирования", отображение / скрытие элементов пользовательского интерфейса, перезагрузка и т. д. UIViewController метод должен вызывать уровень доступа к данным, и поэтому имеет смысл поместить метод на этот уровень в иерархию представления.

Я следовал официальной документации и методам Xamarin и замечательным советам Адама Кемпа.

Для достижения этой цели в Xamarin.IOS существует так много противоречивых методологий. Увы, в настоящее время, похоже, никто не работает в моем случае. Я должен делать что-то в корне неправильно!

У меня есть собственный класс, который наследует от UICollectionViewCell который содержит 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 который имеет public void OnEditModeActivated украшен [Export("OnEditModeActivated:")],

Я вижу, что компилятор запускает исключение "нераспознанный селектор" из-за this (1-й аргумент передан AddTarget) очевидно, что UICollectionViewCell, а не UIViewController и таким образом это будет выглядеть, чтобы решить AddTarget по UICollectionViewCell (экземпляр) -> OnEditActivation (не существует).

Вместо this Мне нужно сослаться на родителя UIViewController но я не хочу передавать его по ссылке на UpdateCell Метод - это будет означать прохождение ссылки через множество уровней, таким образом, мой код станет похож на спагетти.

Если кто-то может объяснить лучший способ, во что бы то ни стало, не стесняйтесь. Я смотрел на повышение события в UICollectionViewCell экземпляр, но безрезультатно. Более того, я не могу понять схему делегирования прямо в Xamarin!

Проблема в том, что я использую иерархию: UIViewController -> UICollectionView -> UICollectionViewSource -> UICollectionViewCell,

Я уверен, что можно вызвать событие / вызов делегата / вызвать метод и решить на уровне контроллера представления...

Спасибо, что нашли время, чтобы помочь в этом.

Всего наилучшего,

Джон

1 ответ

Решение

Проводка _recognizer к ContentView и объявив метод в this исправил мою проблему.

Я изменился:

this.AddGestureRecognizer(_recognizer); 

чтобы:

 cell.ContentView.AddGestureRecognizer(_recognizer);

и создал метод OnLongPressed на том же уровне, украшенном Export["OnLongPressed:"] which raises an event resolved at the Уровень UIViewController`.

Помимо этого, UILongPressGestureRecognizer Вызывает многократные события, и нужно проверить, действительно ли долгое нажатие закончилось, в противном случае любые дальнейшие вызовы событий / методов будут происходить более одного раза, например:

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

UILongPressGestureRecognizer s сработает с несколькими состояниями, которые вы можете проверить, используя State документация по недвижимости здесь.

Другие вопросы по тегам