Поделиться через


События и жесты касания в Xamarin.iOS

Важно понимать события касания и интерфейсы API касания в приложении iOS, так как они являются центральными для всех физических взаимодействий с устройством. Все взаимодействия касания включают UITouch объект. В этой статье мы узнаем, как использовать UITouch класс и его API для поддержки сенсорного ввода. Позже мы расширим наши знания, чтобы узнать, как поддерживать жесты.

Включение сенсорного ввода

Элементы управления в — эти подклассы из UIControl — так зависят от взаимодействия с пользователем, что у них есть жесты, встроенные в UIKit UIKit, поэтому не требуется включить Сенсорный ввод. Он уже включен.

Однако многие из представлений в UIKit ней не включены по умолчанию. Существует два способа включения касания элемента управления. Первым способом является проверка проверка box в области свойств конструктора iOS, как показано на следующем снимке экрана:

Check the User Interaction Enabled checkbox in the Property Pad of the iOS Designer

Кроме того, можно использовать контроллер для задания UserInteractionEnabled свойства true в UIView классе. Это необходимо, если пользовательский интерфейс создается в коде.

Следующая строка кода является примером:

imgTouchMe.UserInteractionEnabled = true;

События касания

Существует три этапа касания, которые возникают, когда пользователь прикасается к экрану, перемещает палец или удаляет палец. Эти методы определены в UIResponder, который является базовым классом для UIView. iOS переопределит связанные методы на UIView устройстве и UIViewController обрабатывать касание:

  • TouchesBegan — Это вызывается при первом касании экрана.
  • TouchesMoved — Это вызывается, когда расположение сенсорного ввода изменяется, так как пользователь скользит пальцами по экрану.
  • TouchesEnded или TouchesCancelledTouchesEnded вызывается при снятии пальцев пользователя с экрана. 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 можно включить несколько касаний, как показано на следующем снимке экрана:

Multi-touch enabled in the iOS Designer

Кроме того, можно программно задать много касание, задав 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 — нажатие и удержание, иногда называемое длинным нажатием или длинным щелчком мыши.

Базовый шаблон использования распознавателя жестов выглядит следующим образом:

  1. Создайте экземпляр распознавателя жестов— сначала создайте экземпляр подкласса UIGestureRecognizer . Объект, созданный экземпляром, будет связан представлением и будет собирать мусор при удалении представления. Не нужно создавать это представление как переменную уровня класса.
  2. Настройка любых параметров жестов — следующий шаг — настройка распознавателя жестов . Ознакомьтесь с документацией UIGestureRecognizer Xamarin и его подклассами для списка свойств, которые можно задать для управления поведением экземпляра UIGestureRecognizer .
  3. Настройка целевого объекта — из-за его Objective-C наследия Xamarin.iOS не вызывает события, когда распознаватель жестов соответствует жесту. UIGestureRecognizer имеет метод — AddTarget который может принимать анонимный делегат или Objective-C селектор с кодом для выполнения при выполнении распознавателя жестов.
  4. Включение распознавателя жестов — как и при использовании событий сенсорного ввода, жесты распознаются только в том случае, если включено взаимодействие с сенсорными элементами.
  5. Добавьте распознаватель жестов в представление . Последний шаг — добавить жест в представление путем вызова View.AddGestureRecognizer и передачи объекта распознавателя жестов.

Дополнительные сведения о реализации в коде см. в примерах распознавателя жестов.

При вызове целевого объекта жеста будет передана ссылка на жест, который произошел. Это позволяет целевому объекту жеста получать сведения о жесте, который произошел. Степень доступной информации зависит от типа распознавателя жестов, который использовался. Дополнительные сведения о данных, доступных для каждого UIGestureRecognizer подкласса, см. в документации Xamarin.

Важно помнить, что после добавления распознавателя жестов в представление представление (и любые представления под ним) не будут получать никаких событий касания. Чтобы разрешить события касания одновременно с жестами, CancelsTouchesInView свойство должно иметь значение false, как показано в следующем коде:

_tapGesture.Recognizer.CancelsTouchesInView = false;

У каждого UIGestureRecognizer есть свойство State, которое предоставляет важные сведения о состоянии распознавателя жестов. При каждом изменении значения этого свойства iOS вызовет метод подписки, предоставляющий ему обновление. Если настраиваемый распознаватель жестов никогда не обновляет свойство State, подписчик никогда не вызывается, отрисовка распознавателя жестов без использования.

Жесты можно суммировать как один из двух типов:

  1. Дискретные — эти жесты запускаются только в первый раз, когда они распознаются.
  2. Непрерывный — эти жесты продолжают работать до тех пор, пока они распознаются.

Распознаватели жестов существуют в одном из следующих состояний:

  • Возможно . Это начальное состояние всех распознавателей жестов. Это значение по умолчанию для свойства State.
  • Начало— когда первый распознанный жест непрерывного распознавания, состояние имеет значение " Начало". Это позволяет подписываться на различие между началом распознавания жестов и изменением.
  • Изменено . После начала непрерывного жеста, но не завершено, состояние будет иметь значение "Изменить каждый раз при перемещении или изменении касания", если он все еще находится в ожидаемых параметрах жеста.
  • Отменено — это состояние будет установлено, если распознаватель пошел с "Начало изменения", а затем касания изменились таким образом, чтобы больше не соответствовать шаблону жеста.
  • Распознанный — состояние будет задано, когда распознаватель жестов соответствует набору касаний и сообщит подписчику о завершении жеста.
  • Завершено — это псевдоним для распознанного состояния.
  • Сбой. Если распознаватель жестов больше не может соответствовать касаниям, для него оно прослушивается, состояние изменится на Failed.

Xamarin.iOS представляет эти значения в UIGestureRecognizerState перечислении.

Работа с несколькими жестами

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

gesture.ShouldRecognizeSimultaneously += (UIGestureRecognizer r) => { return true; };

Кроме того, можно отключить жест в iOS. Существует два свойства делегата, которые позволяют распознаватель жестов изучать состояние приложения и текущих событий касания, принимать решения о том, как и если жест должен быть распознано. Два события:

  1. ShouldReceiveTouch — этот делегат вызывается прямо перед передачей распознавателя жестов и предоставляет возможность исследовать касания и решить, какие касания будут обрабатываться распознавательом жестов.
  2. ShouldBegin — это вызывается, когда распознаватель пытается изменить состояние с "Возможно" на другое состояние. Возвращая значение false, будет принудительно изменено состояние распознавателя жестов на Failed.

Эти методы можно переопределить строго типизированным UIGestureRecognizerDelegate, слабым делегатом или привязать с помощью синтаксиса обработчика событий, как показано в следующем фрагменте кода:

gesture.ShouldReceiveTouch += (UIGestureRecognizer r, UITouch t) => { return true; };

Наконец, можно ставить в очередь распознаватель жестов, чтобы он был успешно выполнен только в случае сбоя другого распознавателя жестов. Например, распознаватель жестов один касания должен быть успешным только при сбое распознавателя жестов двойного касания. В следующем фрагменте кода приведен пример:

singleTapGesture.RequireGestureRecognizerToFail(doubleTapGesture);

Создание пользовательского жеста

Хотя iOS предоставляет некоторые распознаватели жестов по умолчанию, в некоторых случаях может потребоваться создать пользовательские распознавтели жестов. Создание пользовательского распознавателя жестов включает в себя следующие действия.

  1. Подкласс UIGestureRecognizer .
  2. Переопределите соответствующие методы событий касания.
  3. Состояние распознавания пузырька через свойство State базового класса.

Практический пример этого будет описан в пошаговом руководстве using Touch в iOS .