Добавление распознавателя жестов прокрутки

Жест прокрутки возникает при перемещении пальца по горизонтали или вертикальному направлению и часто используется для запуска навигации по содержимому.

Чтобы заставить View распознавать жест прокрутки, создайте экземпляр SwipeGestureRecognizer, задайте для свойства Direction значение перечисления SwipeDirection (Left, Right, Up или Down), при необходимости задайте свойство Threshold, обработайте событие Swiped и добавьте новый распознаватель жестов в коллекцию GestureRecognizers представления. В следующем примере кода показан SwipeGestureRecognizer, присоединенный к BoxView:

<BoxView Color="Teal" ...>
    <BoxView.GestureRecognizers>
        <SwipeGestureRecognizer Direction="Left" Swiped="OnSwiped"/>
    </BoxView.GestureRecognizers>
</BoxView>

Вот эквивалент в коде C#:

var boxView = new BoxView { Color = Color.Teal, ... };
var leftSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Left };
leftSwipeGesture.Swiped += OnSwiped;

boxView.GestureRecognizers.Add(leftSwipeGesture);

Класс SwipeGestureRecognizer также включает в себя свойство Threshold, для которого при необходимости можно задать значение uint, представляющее минимальное расстояние прокрутки, необходимое для распознавания жеста прокрутки, в аппаратно-независимых единицах. Значение по умолчанию для этого свойства равно 100, это означает, что любая прокрутка менее 100 аппаратно-независимых единиц будет игнорироваться.

Распознавание направления прокрутки

В приведенном выше примере свойство Direction задается равным одному значению из перечисления SwipeDirection. Однако также можно задать для этого свойства несколько значений из перечисления SwipeDirection, чтобы событие Swiped активировалось в ответ на прокрутку в более чем одном направлении. Однако при этом действует то ограничение, что отдельный SwipeGestureRecognizer может распознавать только жесты прокрутки по одной оси. Таким образом, жесты прокрутки по горизонтальной оси можно распознать, задав для свойства Direction значения Left и Right:

<SwipeGestureRecognizer Direction="Left,Right" Swiped="OnSwiped"/>

Аналогичным образом, жесты прокрутки по вертикальной оси можно распознать, задав для свойства Direction значения Up и Down:

var swipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Up | SwipeDirection.Down };

Кроме того, для каждого направления жеста прокрутки можно создать SwipeGestureRecognizer, чтобы распознавать такие жесты в каждом направлении:

<BoxView Color="Teal" ...>
    <BoxView.GestureRecognizers>
        <SwipeGestureRecognizer Direction="Left" Swiped="OnSwiped"/>
        <SwipeGestureRecognizer Direction="Right" Swiped="OnSwiped"/>
        <SwipeGestureRecognizer Direction="Up" Swiped="OnSwiped"/>
        <SwipeGestureRecognizer Direction="Down" Swiped="OnSwiped"/>
    </BoxView.GestureRecognizers>
</BoxView>

Вот эквивалент в коде C#:

var boxView = new BoxView { Color = Color.Teal, ... };
var leftSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Left };
leftSwipeGesture.Swiped += OnSwiped;
var rightSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Right };
rightSwipeGesture.Swiped += OnSwiped;
var upSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Up };
upSwipeGesture.Swiped += OnSwiped;
var downSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Down };
downSwipeGesture.Swiped += OnSwiped;

boxView.GestureRecognizers.Add(leftSwipeGesture);
boxView.GestureRecognizers.Add(rightSwipeGesture);
boxView.GestureRecognizers.Add(upSwipeGesture);
boxView.GestureRecognizers.Add(downSwipeGesture);

Примечание.

В приведенных выше примерах один обработчик событий реагирует на возникновение события Swiped. Однако каждый экземпляр SwipeGestureRecognizer при необходимости может использовать другой обработчик событий.

Реагирование на жест прокрутки

Обработчик событий для события Swiped показан в следующем примере:

void OnSwiped(object sender, SwipedEventArgs e)
{
    switch (e.Direction)
    {
        case SwipeDirection.Left:
            // Handle the swipe
            break;
        case SwipeDirection.Right:
            // Handle the swipe
            break;
        case SwipeDirection.Up:
            // Handle the swipe
            break;
        case SwipeDirection.Down:
            // Handle the swipe
            break;
    }
}

SwipedEventArgs можно проверить, чтобы определить направление прокрутки, с помощью пользовательской логики, реагирующей на прокрутку по мере необходимости. Направление жеста прокрутки можно получить из свойства Direction аргументов событий, которому будет присвоено одно из значений из перечисления SwipeDirection. Кроме того, аргументы события также имеют свойство Parameter, которому будет присвоено значение свойства CommandParameter, если оно определено.

С помощью команд

Класс SwipeGestureRecognizer также включает в себя свойства Command и CommandParameter. Эти свойства обычно используются в приложениях на основе шаблона "модель — представление — модель представления" (MVVM). Свойство Command определяет ICommand, вызываемый при распознавании жеста прокрутки, при этом свойство CommandParameter определяет объект, передаваемый в ICommand.. Следующий пример кода показывает, как привязать свойство Command к ICommand, определенному в модели представления, чей экземпляр задан в качестве BindingContext страницы:

var boxView = new BoxView { Color = Color.Teal, ... };
var leftSwipeGesture = new SwipeGestureRecognizer { Direction = SwipeDirection.Left, CommandParameter = "Left" };
leftSwipeGesture.SetBinding(SwipeGestureRecognizer.CommandProperty, "SwipeCommand");
boxView.GestureRecognizers.Add(leftSwipeGesture);

Эквивалентный код XAML:

<BoxView Color="Teal" ...>
    <BoxView.GestureRecognizers>
        <SwipeGestureRecognizer Direction="Left" Command="{Binding SwipeCommand}" CommandParameter="Left" />
    </BoxView.GestureRecognizers>
</BoxView>

SwipeCommand является свойством типа ICommand, определенным в экземпляре модели представления, который задан в качестве BindingContext страницы. Когда жест прокрутки распознается, выполняется метод Execute объекта SwipeCommand. Аргумент для метода Execute — это значение свойства CommandParameter. Дополнительные сведения о командах см. в разделе Командный интерфейс.

Создание контейнера прокрутки

Класс SwipeContainer, показанный в следующем примере кода, является универсальным классом распознавания прокрутки, который используется в качестве оболочки для View, чтобы осуществить распознавание жеста прокрутки:

public class SwipeContainer : ContentView
{
    public event EventHandler<SwipedEventArgs> Swipe;

    public SwipeContainer()
    {
        GestureRecognizers.Add(GetSwipeGestureRecognizer(SwipeDirection.Left));
        GestureRecognizers.Add(GetSwipeGestureRecognizer(SwipeDirection.Right));
        GestureRecognizers.Add(GetSwipeGestureRecognizer(SwipeDirection.Up));
        GestureRecognizers.Add(GetSwipeGestureRecognizer(SwipeDirection.Down));
    }

    SwipeGestureRecognizer GetSwipeGestureRecognizer(SwipeDirection direction)
    {
        var swipe = new SwipeGestureRecognizer { Direction = direction };
        swipe.Swiped += (sender, e) => Swipe?.Invoke(this, e);
        return swipe;
    }
}

Класс SwipeContainer создает объекты SwipeGestureRecognizer для всех четырех направлений прокрутки и присоединяет обработчики событий Swipe. Эти обработчики событий вызывают событие Swipe, определенное SwipeContainer.

В следующем примере кода XAML показан класс SwipeContainer, используемый в качестве оболочки для BoxView:

<ContentPage ...>
    <StackLayout>
        <local:SwipeContainer Swipe="OnSwiped" ...>
            <BoxView Color="Teal" ... />
        </local:SwipeContainer>
    </StackLayout>
</ContentPage>

В следующем примере кода показано, как SwipeContainer используется качестве оболочки для BoxView на странице C#:

public class SwipeContainerPageCS : ContentPage
{
    public SwipeContainerPageCS()
    {
        var boxView = new BoxView { Color = Color.Teal, ... };
        var swipeContainer = new SwipeContainer { Content = boxView, ... };
        swipeContainer.Swipe += (sender, e) =>
        {
          // Handle the swipe
        };

        Content = new StackLayout
        {
            Children = { swipeContainer }
        };
    }
}

Когда BoxView получает жест прокрутки, активируется событие Swiped в SwipeGestureRecognizer. Это обрабатывается классом SwipeContainer, активирующим собственное событие Swipe. Это событие Swipe обрабатывается на странице. SwipedEventArgs можно проверить, чтобы определить направление прокрутки, с помощью пользовательской логики, реагирующей на прокрутку по мере необходимости.