MultiTouch
Multi-Touch XAML Behaviors implementing Multi-Touch Manipulation (Gestures) and Inertia.
Install / Use
/learn @davidezordan/MultiTouchREADME
Multi-Touch Behaviors
XAML Behaviors implementing Multi-Touch Manipulation (Gestures) and Inertia.
Xamarin Forms Behavior uses code from original Xamarin.Forms samples: https://github.com/xamarin/xamarin-forms-samples/tree/master/WorkingWithGestures
Archived projects targeting Silverlight, WPF and Windows Phone 7.x, 8.x available on CodePlex: http://multitouch.codeplex.com/.
Xamarin.Forms: using the PanGestureRecognizer
<p style="text-align: center;"><img class="size-medium wp-image-7904 aligncenter" src="https://davide.dev/wp-content/uploads/2016/02/Using-PanGestureRecognizer.png" alt="Using the PanGestureRecognizer" width="256" height="500"></p> <p style="text-align: justify;">Recently I've blogged about Xamarin.Forms and how to create a XAML Behavior for enabling Multi-Touch gestures to generic elements and implementing a scale / pinch functionality.</p> <p style="text-align: justify;">Fortunately the framework provides <a href="https://developer.xamarin.com/guides/xamarin-forms/user-interface/gestures/" target="_blank" rel="noopener noreferrer">three types of recognizer</a> that greatly simplify the implementation:</p> <ul> <li style="text-align: justify;"><strong>PinchGestureRecognizer</strong> allows user interactions for zoom / scale functionalities;</li> <li style="text-align: justify;"><strong>PanGestureRecognizer</strong> enables pan / translate transformations;</li> <li style="text-align: justify;"><strong>TapGestureRecognizer</strong> detects tap events.</li> </ul> <p style="text-align: justify;">Yesterday I decided to try the <strong>PanGestureRecognizer </strong>for extending the capabilities of the Behavior described in the previous post.</p> <p style="text-align: justify;">First of all, I added two <em>Bindable</em> properties in order to permit activation / deactivation of individual gestures (<em>Bindable</em> properties are equivalent to <em>Dependency</em> ones in UWP XAML)</p> <pre class="lang:default decode:true" title="IsTranslateEnabled and IsScaleEnabled Bindable properties">#region IsScaleEnabled property /// <summary> /// Identifies the <see cref="IsScaleEnabledProperty" /> property. /// </summary> public static readonly BindableProperty IsScaleEnabledProperty = BindableProperty.Create<MultiTouchBehavior, bool>(w => w.IsScaleEnabled, default(bool)); /// <summary> /// Identifies the <see cref="IsScaleEnabled" /> dependency / bindable property. /// </summary> public bool IsScaleEnabled { get { return (bool)GetValue(IsScaleEnabledProperty); } set { SetValue(IsScaleEnabledProperty, value); } } #endregion #region IsTranslateEnabled property /// <summary> /// Identifies the <see cref="IsTranslateEnabledProperty" /> property. /// </summary> public static readonly BindableProperty IsTranslateEnabledProperty = BindableProperty.Create<MultiTouchBehavior, bool>(w => w.IsTranslateEnabled, default(bool)); /// <summary> /// Identifies the <see cref="IsTranslateEnabled" /> dependency / bindable property. /// </summary> public bool IsTranslateEnabled { get { return (bool)GetValue(IsTranslateEnabledProperty); } set { SetValue(IsTranslateEnabledProperty, value); } } #endregion</pre> <p style="text-align: justify;">In this way we can specify in our XAML what gestures are enabled:</p> <pre class="lang:default decode:true ">... <Image.Behaviors> <behaviors:MultiTouchBehavior IsScaleEnabled="True" IsTranslateEnabled="True" /> </Image.Behaviors> ...</pre> <p style="text-align: justify;">Then I initialised the GestureRecognizers adding a new <strong>PanGestureRecognizer </strong>to the recognizers list:</p> <pre class="lang:default decode:true ">/// <summary> /// Initialise the Gesture Recognizers. /// </summary> private void InitialiseRecognizers() { _panGestureRecognizer = new PanGestureRecognizer(); } /// <summary> /// Occurs when BindingContext is changed: used to initialise the Gesture Recognizers. /// </summary> /// <param name="sender">The sender object.</param> /// <param name="e">The event parameters.</param> private void AssociatedObjectBindingContextChanged(object sender, EventArgs e) { _parent = _associatedObject.Parent as ContentView; _parent?.GestureRecognizers.Remove(_panGestureRecognizer); _parent?.GestureRecognizers.Add(_panGestureRecognizer); }</pre> <p style="text-align: justify;">And subscribed to the <strong>PanUpdated</strong> event in order to apply the translate transform:</p> <pre class="lang:default decode:true ">/// <summary> /// Initialise the events. /// </summary> private void InitializeEvents() { CleanupEvents(); _panGestureRecognizer.PanUpdated += OnPanUpdated; }</pre> <p style="text-align: justify;">The implementation of this event handler permits to update the X and Y coordinates of the element when a Pan gesture is detected:</p> <pre class="lang:default decode:true " title="PanUpdated event handler implementation">/// <summary> /// Implements Pan/Translate. /// </summary> /// <param name="sender">The sender object.</param> /// <param name="e">The event parameters.</param> private void OnPanUpdated(object sender, PanUpdatedEventArgs e) { if (_parent == null) { return; } if (!IsTranslateEnabled) { return; } switch (e.StatusType) { case GestureStatus.Running: _parent.Content.TranslationX = _xOffset + e.TotalX; _parent.Content.TranslationY = _yOffset + e.TotalY; break; case GestureStatus.Completed: _xOffset = _parent.Content.TranslationX; _yOffset = _parent.Content.TranslationY; break; } }</pre> <p style="text-align: justify;">Here we go: the sample app can now be deployed to the emulators and iOS / Android / Windows devices.</p> <p style="text-align: justify;">Just a couple of notes:</p> <ul> <li style="text-align: justify;">deployment to iOS required this <a href="http://codeworks.it/blog/?p=242" target="_blank" rel="noopener noreferrer">workaround</a> to work properly since the new sample app uses different assemblies;</li> <li style="text-align: justify;">Project has been updated to Visual Studio 2019 and Xamarin.Forms 3.6.0.</li> </ul>Related Skills
node-connect
334.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
82.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
334.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
82.3kCommit, push, and open a PR
