UWP и эволюция разработки для сенсорного взаимодействия

Как программирование для сенсорного взаимодействия на универсальной платформе Windows (UWP) отличается от разработки для мыши и клавиатуры в Windows Forms? Эта публикация расскажет о некоторых тонких различиях между ними и о том, как использовать самые современные инструменты для создания пользовательского опыта для сенсорного взаимодействия.

Рис. 1. Командная строка

На протяжении многих лет мы взаимодействовали с нашими компьютерами. В течение длительного времени взаимодействие осуществлялось с помощью клавиатуры. Затем появился графический пользовательский интерфейс (GUI), который не только ввел мышь, но и резко изменил внешний вид домашних экранов и приложений. Успех Windows 95 и Mac OS укрепил этот пользовательский интерфейс, популяризировал персональные вычисления и изменил наш компьютерный ландшафт.


Рис. 2. Графический пользовательский интерфейс в Windows Form

Хотя естественные пользовательские интерфейсы (NUI) существуют уже давно, переход к сенсорным интерфейсам произошел как более постепенно, так и более спокойно. Отчасти это происходит из-за того, что это произошло рука об руку с ростом мобильных компьютеров на основе смартфонов — и у нас есть тенденция не видеть наши телефоны в качестве центров вычислительной мощности, а скорее как аксессуары или гаджеты. Частично, тем не менее, плавный переход произошел, потому что создатели средств разработки, таких как Visual Studio, предприняли сознательное усилие, чтобы защитить разработчиков от этих изменений, сделав сенсорную составляющую и мышь (или тап и щелчок), по-видимому, одним и тем же. Как следствие, мы перешли от ориентированного на мышь мира к миру сенсорного взаимодействия, не замечая тектонического сдвига, который произошел под нашими ногами.

Что означает дружеский подход к сенсорному взаимодействию?
Когда планшеты с сенсорным экраном впервые появились для Windows, вы почти всегда просто использовали свой палец, как если бы мышь манипулировала приложениями, предназначенными для мыши. Это было сложно, потому что кнопки, как правило, были слишком маленькими, и вы не могли видеть визуальные элементы, предназначенные для взаимодействия с мышью, скрытые под пальцами. Даже если ваше устройство поддерживало сенсорный режим, приложения, работающие на нем, продолжали быть ориентироваться на взаимодействие с помощью мыши. Аналогичным образом, на ранних мобильных устройствах появился стилус, потому что стилус мог манипулировать этими крошечными кнопками.


Рис 3. Естественный пользовательский интерфейс в Windows Phone

Телефонные приложения отметились переходом от ориентированного на мышь к сенсорному взаимодействию. Разумеется, телефонные приложения были не просто ориентированными на касания. Они были ориентированы исключительно на касания. Они вносили изменения в дизайн, макет и элементы управления, используемые в приложениях, чтобы упростить взаимодействие пользователей смартфонов. В свою очередь, они были включены в платформу UWP. В то время как платформа UWP поддерживает взаимодействие с сенсорным экраном и мышью, а также множество других методов ввода, когда вы разрабатываете приложения и элементы управления для этого, вы должны в первую очередь подумать о нём как о сенсорном интерфейсе. Взаимодействие с мышью должно быть добавлено вторично.
Есть много совпадений между сенсорными жестами и взаимодействиями с помощью мыши, которые делают это проще. Например, когда вы касаетесь кнопки UWP или кликаете на нее, запускаются событие Tapped и событие Click. Точно так же события, такие как ManipulationStarted и ManipulationCompleted, не различают касание и использование мыши. Учитывая количество усилий, которые привели к размыванию разницы между касанием и использованием мыши в UWP, стоит спросить себя, когда клик не будет работать как клик?

Застаревший вопрос: клик или тап
Элемент управления Button — интересный остров обработчиков поведения GUI в мире ориентированном на сенсорное взаимодействие. Если вы дважды щелкните по кнопке в дизайнере Visual Studio, Visual Studio подключит обработчик событий Click для вас в XAML и в коде. Это имеет место для обратной совместимости, поскольку, как было указано выше, сенсорные взаимодействия и взаимодействия с помощью мыши будут обрабатываться событиями как Click, так и Tapped.
Однако для того, чтобы разрабатывать по пути ориентированному в первую очередь на сенсорное взаимодействие, вы должны обрабатывать событие Tapped, а не Click. Это становится важным, когда вам нужно отличить Tapped от других событий касания, таких как DoubleTapped и Holding (последнее нельзя даже эмулировать мышью).

  1. <Button Content=«My Button»
  2. Click=«Button_Click»
  3. Tapped=«Button_Tapped»
  4. RightTapped=«Button_RightTapped»
  5. DoubleTapped=«Button_DoubleTapped»
  6. Holding=«Button_Holding»
  7. ManipulationMode=«All»
  8. ManipulationStarted=«Button_ManipulationStarted»
  9. ManipulationCompleted=«Button_ManipulationCompleted»
  10. />

Как только вы убедитесь, что ваше приложение хорошо работает с прикосновениями, вы должны добавить взаимодействия для мыши и других методов ввода. Например, вы можете захватывать клики правой кнопки мыши, обрабатывая странно названное событие RightTapped.

  1. <VisualStateManager.VisualStateGroups>
  2. <VisualStateGroup x:Name=«CommonStates»>
  3. <VisualState x:Name=«Normal» />
  4. <VisualState x:Name=«PointerOver»/>
  5. <VisualState x:Name=«Pressed»/>
  6. </VisualStateGroup>
  7. </VisualStateManager.VisualStateGroups>

Что еще более важно, вы также должны иметь визуальные состояния для зависания над элементом управления (PointerOver) и состояния Pressed. В сенсорном мире это не особенно полезно, так как ваши пальцы, как правило, закрывают эти анимации. Однако визуальные возможности и визуальная обратная связь могут быть чрезвычайно полезны для взаимодействия с помощью мыши, пера и сенсорной панели, которые не блокируют просмотр пользователем.

Правильное прокручивание: онлайн и офлайн жесты
Жесты касания бывают двух видов. Существуют прямые манипуляции с объектами, которые происходят автоматически, когда вы перемещаете один или несколько пальцев по экрану. Они иногда также называются онлайн жестами. Другой вид жестов будет успешным только после того, как пользователь выполнит ряд шагов, таких как перемещение объекта на экране с одной позиции на некоторое смещение от этой позиции, например, свайп. Эти жесты легко идентифицировать, поскольку они включают пороговые значения. Если пользователь не перемещает объект достаточно далеко, он не превысит порог расстояния. Если он не завершит движение за определенное время, он не выполнит пороговое значение времени. Они также известны как оффлайн жесты.

  1. <Canvas ManipulationMode=«None» Margin=«0,12,0,0» MinHeight=«400»>
  2. <Border x:Name=«manipulateMe»
  3. ManipulationMode=«All»
  4. ManipulationDelta=«ManipulateMe_ManipulationDelta»
  5. Background=«LightGray» Height=«200» Width=«200»
  6. HorizontalAlignment=«Left»
  7. VerticalAlignment=«Top»/>
  8. </Canvas>

Прямые манипуляции могут быть реализованы в XAML, используя различные события манипуляции с UIElement. Хотя событие ManipulationStarting может быть полезным, единственным событием, которое вам действительно нужно обработать, является ManipulationDelta. Вы также захотите установить свойство ManipulationMode, которое определяет, какие виды манипуляций разрешены, например, Scale, Rotate, TranslateY, TranslateX. Все они разрешают любые прямые манипуляции с целевым элементом.

  1. private TransformGroup transforms;
  2. private MatrixTransform previousTransform;
  3. private CompositeTransform deltaTransform;
  4. private void InitManipulationTransforms()
  5. {
  6. transforms = new TransformGroup();
  7. previousTransform = new MatrixTransform() { Matrix = Matrix.Identity };
  8. deltaTransform = new CompositeTransform();
  9. transforms.Children.Add(previousTransform);
  10. transforms.Children.Add(deltaTransform);
  11. // Set the render transform on the rect
  12. manipulateMe.RenderTransform = transforms;
  13. }

Чтобы перемещать и поворачивать целевой UIElement, вам нужно отслеживать применяемые к нему преобразования.

  1. void ManipulateMe_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
  2. {
  3. previousTransform.Matrix = transforms.Value;
  4. // Get center point for rotation
  5. Point center = previousTransform.TransformPoint(new Point(e.Position.X, e.Position.Y));
  6. deltaTransform.CenterX = center.X;
  7. deltaTransform.CenterY = center.Y;
  8. // Look at the Delta property of the ManipulationDeltaRoutedEventArgs to retrieve
  9. // the rotation, scale, X, and Y changes
  10. deltaTransform.Rotation = e.Delta.Rotation;
  11. deltaTransform.TranslateX = e.Delta.Translation.X;
  12. deltaTransform.TranslateY = e.Delta.Translation.Y;
  13. }

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

Делайте сенсорные манипуляции гладкими, как масло
Сегодняшние пользователи ожидают, что взаимодействие с контентом через сенсорное управление будет плавным и отзывчивым. Использование событий ManipulationDelta не может полностью гарантировать это, потому что оно работает в потоке пользовательского интерфейса. Когда в потоке пользовательского интерфейса происходит большая обработка, пользователи могут испытывать некоторое отставание в ответ на их жесты касания.
Чтобы получить лучший опыт взаимодействия через касания, важно перенести обработку касания из потока пользовательского интерфейса, используя класс InteractionTracker. InteractionTracker был представлен с API-интерфейсом Composition и позволяет осуществлять взаимодействие и визуальную обратную связь на гораздо более низком уровне, чем предыдущие модели программирования пользовательского интерфейса в UWP. Чтобы управлять анимацией композиции с помощью InteractionTracker, вам необходимо связать ее с VisualInteractionSource. В приведенном ниже примере кода источник является визуальным средством поддержки для корневого элемента страницы.

  1. _tracker = InteractionTracker.Create(_compositor);
  2. var interactionSource = VisualInteractionSource.Create(viewportVisual);
  3. interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia;
  4. interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia;
  5. _tracker.InteractionSources.Add(interactionSource);
  6. // bind the InteractionTracker outputs to the contentVisual.
  7. var positionExpression = _compositor.CreateExpressionAnimation(«-tracker.Position»);
  8. positionExpression.SetReferenceParameter(«tracker», _tracker);
  9. contentVisual.StartAnimation(«Offset», positionExpression);

Для еще более сложной реализации сенсорного ввода с низкой задержкой вы можете использовать класс CoreIndependentInputSource, как показано в этом примере на GitHub.

Замыкая круг
Потребовалось много времени, чтобы перейти от подсказок DOS к естественному пользовательскому интерфейсу. Одна из особенностей всех этих изменений пользовательского опыта заключается в том, что вместо того, чтобы вытеснять друг друга, эти варианты просто дополняют друг друга. Клавиатура никогда не уходила, и, как оживление виниловых пластинок, популярность PowerShell и Linux Bash Shell в Windows предполагает, что командные подсказки тоже не исчезнут. Для получения дополнительной информации о сенсорных взаимодействиях, пожалуйста, следуйте этим ссылкам:
Input primer
Сенсорные взаимодействияs
Рекомендации по проектированию: сенсорные взаимодействия
Guidelines for targeting
Basic input sample code

Перевод оригинальной публикации UWP and the evolution of touch Development
Автор: Windows Apps Team
Перевод: Сергей Урусов

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *