Skip to content

Adding touch events - #309

Merged
mattleibow merged 11 commits into
masterfrom
touch-events
Jun 9, 2017
Merged

mattleibow merged 11 commits into
masterfrom
touch-events

Conversation

@mattleibow

@mattleibow mattleibow commented Jun 1, 2017 •

Copy link
Copy Markdown
Contributor
public class SKTouchActionEventArgs : EventArgs
{
	public long Id;
	public SKTouchActionType ActionType;
	public SKTouchDeviceType DeviceType;
	public SKMouseButton MouseButton;
	public SKPoint Location;
	public bool InContact;
}

public enum SKTouchActionType
{
	Entered,
	Pressed,
	Moved,
	Released,
	Cancelled,
	Exited,
}

public enum SKTouchDeviceType
{
	Touch,
	Mouse,
	Pen
}

public enum SKMouseButton
{
	Unknown,
	Left,
	Middle,
	Right
}

 - switch between gestures and touch events
 - improved performance as we don't need to listen always
@mattleibow

mattleibow commented Jun 3, 2017 •

Copy link
Copy Markdown
Contributor Author

All the views will get the Touch event, with similar features. However, due to platform differences there are some limitations or restrictions.

There is a property, EnableTouchEvents (default value is false), that can be used to enable/disable touch events. This has two main benefits:

  1. The ability to subscribe to or completely unsubscribe from all touch events
  2. Some Xamarin.Forms platforms cannot receive touch events and use gesture recognizers simultaneously

Setting this property to false will result in the touch events being completely disabled. Setting it to true may override existing Xamarin.Forms gesture recognizers.

This property is used to control the platforms:

  • iOS and Android cannot support touch events and Xamarin.Forms gesture recognizers simultaneously
  • macOS and UWP technically don't require this as both touch events and Xamarin.Forms gesture recognizers work simultaneously

Android:

  • Touch events are consumed via the Touch event, or the IOnTouchListener
  • Because the touch events are redirected to the listener, parent views cannot receive touch events
  • Because the parent view cannot receive events, the Xamarin.Forms gesture recognizers won't work

iOS:

macOS:

  • Touch events are managed via a NSGestureRecognizer
  • Touch events do not disable the the Xamarin.Forms gesture recognizers

UWP:

  • Touch events are managed via the pointer events
  • Touch events do not disable the the Xamarin.Forms gesture recognizers

@michaelstonis

Copy link
Copy Markdown

Any considerations for multitouch? I personally feel like having an event with a single touch point is pretty great for nearly all situations, so the implementation here makes that nice and clean. If I wanted to do any kinds of pinch style event, I suppose you could switch to a pinch gesture. For what it is worth, pinch and rotate are the two primary use cases that I can think of for multitouch.

@mattleibow

Copy link
Copy Markdown
Contributor Author

Multitouch is supported fully. The Id property on the event args tracks the various pointers.

I have been testing with a sample like this, which i have gotten at least 10 pointers (I ran out of fingers):

private readonly Dictionary<long, SKPoint> points = new Dictionary<long, SKPoint>();

private void OnTouching(object sender, SKTouchEventArgs e)
{
	switch (e.ActionType)
	{
		case SKTouchAction.Entered:
		case SKTouchAction.Pressed:
		case SKTouchAction.Moved:
			points[e.Id] = e.Location;
			break;
		case SKTouchAction.Released:
		case SKTouchAction.Cancelled:
		case SKTouchAction.Exited:
			points.Remove(e.Id);
			break;
	}

	((SKCanvasView)sender).InvalidateSurface();
}

@mattleibow
mattleibow merged commit 13fd5bc into master Jun 9, 2017
@mattleibow
mattleibow deleted the touch-events branch June 9, 2017 16:19
@darylwatts

Copy link
Copy Markdown

Just as an aside to this - I am currently using SkiaSharp in a Xamarin Forms project (works great!) and using these features on Android (not tested iOS yet) - and I have a canvas view with Pan and Pinch Xamarin forms gestures attached to it, and the SkiaSharp touch events enabled on it too, and they all work really nicely together. I can pan and pinch, and tap to get the location/point that I need.

NB - also the iOS bug mentioned above has been fixed in Xamarin forms 2.3.6-pre1 and onwards.

@ghost

ghost commented May 3, 2018

Copy link
Copy Markdown

@darylwatts You said all three (pinch, pan and touch) work together nicely. However when I try to pinch or pan, my code always gets to the touch eventhandler of the SKCanvasView first, and after that it gets to the pinch/pan code. Because of this, pinching or panning isn't as smooth as it should be. It's laggy, and sometimes it just won't work.
In the touch event, I thought it would be best to use the SKTouchAction.Released to run my touch code, but it never gets there. Only when I use Pressed, it gets to the code.
Do you have any suggestions on how to improve the pinching/panning? Am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants