События и жесты касания в Xamarin.iOS
Важно понимать события касания и интерфейсы API касания в приложении iOS, так как они являются центральными для всех физических взаимодействий с устройством. Все взаимодействия касания включают UITouch
объект. В этой статье мы узнаем, как использовать UITouch
класс и его API для поддержки сенсорного ввода. Позже мы расширим наши знания, чтобы узнать, как поддерживать жесты.
Включение сенсорного ввода
Элементы управления в — эти подклассы из UIControl — так зависят от взаимодействия с пользователем, что у них есть жесты, встроенные в UIKit
UIKit, поэтому не требуется включить Сенсорный ввод. Он уже включен.
Однако многие из представлений в UIKit
ней не включены по умолчанию. Существует два способа включения касания элемента управления. Первым способом является проверка проверка box в области свойств конструктора iOS, как показано на следующем снимке экрана:
Кроме того, можно использовать контроллер для задания UserInteractionEnabled
свойства true в UIView
классе. Это необходимо, если пользовательский интерфейс создается в коде.
Следующая строка кода является примером:
imgTouchMe.UserInteractionEnabled = true;
События касания
Существует три этапа касания, которые возникают, когда пользователь прикасается к экрану, перемещает палец или удаляет палец. Эти методы определены в UIResponder
, который является базовым классом для UIView. iOS переопределит связанные методы на UIView
устройстве и UIViewController
обрабатывать касание:
TouchesBegan
— Это вызывается при первом касании экрана.TouchesMoved
— Это вызывается, когда расположение сенсорного ввода изменяется, так как пользователь скользит пальцами по экрану.TouchesEnded
илиTouchesCancelled
—TouchesEnded
вызывается при снятии пальцев пользователя с экрана.TouchesCancelled
вызывается, если iOS отменяет сенсорный ввод, например, если пользователь скользит пальцем от кнопки, чтобы отменить нажатие.
Сенсорные события рекурсивно перемещаются по стеку uiViews, чтобы проверка, если событие касания находится в пределах объекта представления. Это часто называется Хит-тестирование. Сначала они будут вызываться в верхней части UIView
или UIViewController
затем будут вызываться на UIView
их и UIViewControllers
ниже в иерархии представлений.
UITouch
Объект будет создан каждый раз, когда пользователь прикасается к экрану. Объект UITouch
включает данные об касании, например, когда произошло касание, где оно произошло, если касание было пальцем и т. д. События касания передаются свойством касаний — NSSet
содержащим один или несколько касаний. Это свойство можно использовать для получения ссылки на касание и определения ответа приложения.
Классы, переопределиющие одно из событий касания, должны сначала вызвать базовую реализацию, а затем получить UITouch
объект, связанный с событием. Чтобы получить ссылку на первое касание, вызовите AnyObject
свойство и приведите его как показанное UITouch
в следующем примере:
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
UITouch touch = touches.AnyObject as UITouch;
if (touch != null)
{
//code here to handle touch
}
}
iOS автоматически распознает последовательные быстрые касания на экране и собирает их все как один касание в одном UITouch
объекте. Это делает проверка для двойного касания так же просто, как проверка свойствTapCount
, как показано в следующем коде:
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
UITouch touch = touches.AnyObject as UITouch;
if (touch != null)
{
if (touch.TapCount == 2)
{
// do something with the double touch.
}
}
}
Multi-Touch
По умолчанию для элементов управления много сенсорный режим не включен. В конструкторе iOS можно включить несколько касаний, как показано на следующем снимке экрана:
Кроме того, можно программно задать много касание, задав MultipleTouchEnabled
свойство, как показано в следующей строке кода:
imgTouchMe.MultipleTouchEnabled = true;
Чтобы определить, сколько пальцев касалось экрана, используйте Count
свойство в свойстве UITouch
:
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
lblNumberOfFingers.Text = "Number of fingers: " + touches.Count.ToString();
}
Определение расположения касания
Метод UITouch.LocationInView
возвращает объект CGPoint, содержащий координаты касания в заданном представлении. Кроме того, мы можем проверить, находится ли это расположение в элементе управления путем вызова метода Frame.Contains
. В следующем фрагменте кода показан пример:
if (this.imgTouchMe.Frame.Contains (touch.LocationInView (this.View)))
{
// the touch event happened inside the UIView imgTouchMe.
}
Теперь, когда у нас есть представление о событиях касания в iOS, давайте рассмотрим распознаватель жестов.
Распознаватели жестов
Распознаватель жестов может значительно упростить и сократить усилия по программированию для поддержки сенсорного взаимодействия в приложении. Распознаватель жестов iOS объединяет ряд событий касания в одно сенсорное событие.
Xamarin.iOS предоставляет класс UIGestureRecognizer
в качестве базового класса для следующих встроенных распознавателей жестов:
- UITapGestureRecognizer — это для одного или нескольких касаний.
- UIPinchGestureRecognizer — сцепление и распределение пальцев.
- UIPanGestureRecognizer — сдвиг или перетаскивание.
- UISwipeGestureRecognizer — swiping в любом направлении.
- UIRotationGestureRecognizer — поворот двух пальцев в по часовой стрелке или по часовой стрелке.
- UILongPressGestureRecognizer — нажатие и удержание, иногда называемое длинным нажатием или длинным щелчком мыши.
Базовый шаблон использования распознавателя жестов выглядит следующим образом:
- Создайте экземпляр распознавателя жестов— сначала создайте экземпляр подкласса
UIGestureRecognizer
. Объект, созданный экземпляром, будет связан представлением и будет собирать мусор при удалении представления. Не нужно создавать это представление как переменную уровня класса. - Настройка любых параметров жестов — следующий шаг — настройка распознавателя жестов . Ознакомьтесь с документацией
UIGestureRecognizer
Xamarin и его подклассами для списка свойств, которые можно задать для управления поведением экземпляраUIGestureRecognizer
. - Настройка целевого объекта — из-за его Objective-C наследия Xamarin.iOS не вызывает события, когда распознаватель жестов соответствует жесту.
UIGestureRecognizer
имеет метод —AddTarget
который может принимать анонимный делегат или Objective-C селектор с кодом для выполнения при выполнении распознавателя жестов. - Включение распознавателя жестов — как и при использовании событий сенсорного ввода, жесты распознаются только в том случае, если включено взаимодействие с сенсорными элементами.
- Добавьте распознаватель жестов в представление . Последний шаг — добавить жест в представление путем вызова
View.AddGestureRecognizer
и передачи объекта распознавателя жестов.
Дополнительные сведения о реализации в коде см. в примерах распознавателя жестов.
При вызове целевого объекта жеста будет передана ссылка на жест, который произошел. Это позволяет целевому объекту жеста получать сведения о жесте, который произошел. Степень доступной информации зависит от типа распознавателя жестов, который использовался. Дополнительные сведения о данных, доступных для каждого UIGestureRecognizer
подкласса, см. в документации Xamarin.
Важно помнить, что после добавления распознавателя жестов в представление представление (и любые представления под ним) не будут получать никаких событий касания. Чтобы разрешить события касания одновременно с жестами, CancelsTouchesInView
свойство должно иметь значение false, как показано в следующем коде:
_tapGesture.Recognizer.CancelsTouchesInView = false;
У каждого UIGestureRecognizer
есть свойство State, которое предоставляет важные сведения о состоянии распознавателя жестов. При каждом изменении значения этого свойства iOS вызовет метод подписки, предоставляющий ему обновление. Если настраиваемый распознаватель жестов никогда не обновляет свойство State, подписчик никогда не вызывается, отрисовка распознавателя жестов без использования.
Жесты можно суммировать как один из двух типов:
- Дискретные — эти жесты запускаются только в первый раз, когда они распознаются.
- Непрерывный — эти жесты продолжают работать до тех пор, пока они распознаются.
Распознаватели жестов существуют в одном из следующих состояний:
- Возможно . Это начальное состояние всех распознавателей жестов. Это значение по умолчанию для свойства State.
- Начало— когда первый распознанный жест непрерывного распознавания, состояние имеет значение " Начало". Это позволяет подписываться на различие между началом распознавания жестов и изменением.
- Изменено . После начала непрерывного жеста, но не завершено, состояние будет иметь значение "Изменить каждый раз при перемещении или изменении касания", если он все еще находится в ожидаемых параметрах жеста.
- Отменено — это состояние будет установлено, если распознаватель пошел с "Начало изменения", а затем касания изменились таким образом, чтобы больше не соответствовать шаблону жеста.
- Распознанный — состояние будет задано, когда распознаватель жестов соответствует набору касаний и сообщит подписчику о завершении жеста.
- Завершено — это псевдоним для распознанного состояния.
- Сбой. Если распознаватель жестов больше не может соответствовать касаниям, для него оно прослушивается, состояние изменится на Failed.
Xamarin.iOS представляет эти значения в UIGestureRecognizerState
перечислении.
Работа с несколькими жестами
По умолчанию iOS не разрешает одновременно выполнять жесты по умолчанию. Вместо этого каждый распознаватель жестов получит события касания в недетерминированном порядке. В следующем фрагменте кода показано, как одновременно выполнять распознаватель жестов:
gesture.ShouldRecognizeSimultaneously += (UIGestureRecognizer r) => { return true; };
Кроме того, можно отключить жест в iOS. Существует два свойства делегата, которые позволяют распознаватель жестов изучать состояние приложения и текущих событий касания, принимать решения о том, как и если жест должен быть распознано. Два события:
- ShouldReceiveTouch — этот делегат вызывается прямо перед передачей распознавателя жестов и предоставляет возможность исследовать касания и решить, какие касания будут обрабатываться распознавательом жестов.
- ShouldBegin — это вызывается, когда распознаватель пытается изменить состояние с "Возможно" на другое состояние. Возвращая значение false, будет принудительно изменено состояние распознавателя жестов на Failed.
Эти методы можно переопределить строго типизированным UIGestureRecognizerDelegate
, слабым делегатом или привязать с помощью синтаксиса обработчика событий, как показано в следующем фрагменте кода:
gesture.ShouldReceiveTouch += (UIGestureRecognizer r, UITouch t) => { return true; };
Наконец, можно ставить в очередь распознаватель жестов, чтобы он был успешно выполнен только в случае сбоя другого распознавателя жестов. Например, распознаватель жестов один касания должен быть успешным только при сбое распознавателя жестов двойного касания. В следующем фрагменте кода приведен пример:
singleTapGesture.RequireGestureRecognizerToFail(doubleTapGesture);
Создание пользовательского жеста
Хотя iOS предоставляет некоторые распознаватели жестов по умолчанию, в некоторых случаях может потребоваться создать пользовательские распознавтели жестов. Создание пользовательского распознавателя жестов включает в себя следующие действия.
- Подкласс
UIGestureRecognizer
. - Переопределите соответствующие методы событий касания.
- Состояние распознавания пузырька через свойство State базового класса.
Практический пример этого будет описан в пошаговом руководстве using Touch в iOS .