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
документация по недвижимости здесь.