{"id":37989,"date":"2018-09-19T13:52:00","date_gmt":"2018-09-19T17:52:00","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=37989"},"modified":"2019-03-25T14:07:20","modified_gmt":"2019-03-25T22:07:20","slug":"apple-pencil-handling-input","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/apple-pencil-handling-input\/","title":{"rendered":"Handling input from Apple Pencil"},"content":{"rendered":"<p>\t\t\t\tAfter months of contemplation before finally buying an Apple Pencil to go along with the iPad Pro, it turns out it is as magical as they say! This blog post describes how to use Xamarin.iOS and Visual Studio 2017 to build a signature pad app that works with Apple Pencil.<\/p>\n<h3>Testing the Apple Pencil Input<\/h3>\n<p>While it is possible to use the iOS Simulator to test Apple Pencil input, it\u2019s always best to test on a physical device. There \u2013 now you have a reason to upgrade! Start by creating a <strong>Single View App<\/strong> in Visual Studio 2017. Open <strong>Main.storyboard<\/strong> and drag an <strong>Image View<\/strong> to the design surface:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-medium\" src=\"https:\/\/i.imgur.com\/KVivtB0.png\" alt=\"new project\" width=\"1000\" height=\"603\" \/><\/p>\n<h3>Add New UIImageView<\/h3>\n<p>To add a new <strong>UIImageView<\/strong> outlet to (<strong>filename<\/strong>):<\/p>\n<ul>\n<li>Set the <strong>Name<\/strong> of the image view to <strong>signaturePad<\/strong><\/li>\n<li>Check <strong>Enable User Interaction<\/strong><\/li>\n<li>Set the <strong>Class<\/strong> to <strong>SignatureView<\/strong><\/li>\n<li>Press return.<\/li>\n<\/ul>\n<p>iOS interprets Apple Pencil input as standard touch inputs but with additional properties, to support writing, add code to handle the touch events:<\/p>\n<pre><code>public override void TouchesMoved(NSSet touches, UIEvent evt)\r\n{\r\n    \/\/ 1\r\n    var touch = touches.ToArray().FirstOrDefault();\r\n    if (touch == null)\r\n        return;\r\n\r\n    \/\/ 2\r\n    UIGraphics.BeginImageContextWithOptions(Bounds.Size, false, 0);\r\n    var context = UIGraphics.GetCurrentContext();\r\n    Image?.Draw(Bounds);\r\n\r\n    DrawLine(context, touch);\r\n    Image = UIGraphics.GetImageFromCurrentImageContext();\r\n\r\n    \/\/3\r\n    UIGraphics.EndImageContext();\r\n}<\/code><\/pre>\n<p>This code does the following things:<\/p>\n<ol>\n<li>Gets the touch information from the event; this will be used to draw the line.<\/li>\n<li>Creates a Core Graphics image context that draws the lines on the screen by calling DrawLine method.<\/li>\n<li>Close the context.<\/li>\n<\/ol>\n<p>The <strong>DrawLine<\/strong> methods processes the touch information:<\/p>\n<pre><code>UIColor color = UIColor.Blue;\r\nnfloat width = 4;\r\nnfloat force = 4;\r\n\r\n...\r\n\r\nvoid DrawLine(CGContext context, UITouch touch)\r\n{\r\n    \/\/1\r\n    var previousLocation = touch.PreviousLocationInView(this);\r\n    var location = touch.LocationInView(this);\r\n\r\n    \/\/2\r\n    context.SetStrokeColor(color.CGColor);\r\n    context.SetLineWidth(width);\r\n    context.SetLineCap(CGLineCap.Round);\r\n\r\n    \/\/3\r\n    context.MoveTo(previousLocation.X, previousLocation.Y);\r\n    context.AddLineToPoint(location.X, location.Y);\r\n\r\n    \/\/4\r\n    context.StrokePath();\r\n}<\/code><\/pre>\n<p>This code:<\/p>\n<ol>\n<li>Determines where to draw a line by looking at the previous and current touch locations.<\/li>\n<li>Sets the line properties.<\/li>\n<li>Creates a path.<\/li>\n<li>Draws the line by creating a stroke along the path.<\/li>\n<\/ol>\n<h3>Using the Apple Pencil<\/h3>\n<p>At this point, the app is ready to use Apple Pencil. The iPad\u2019s palm rejection prevents your palm from interfering with the writing:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-medium\" src=\"https:\/\/i.imgur.com\/RzSZb8U.png\" alt=\"finger input\" width=\"1000\" height=\"750\" \/><\/p>\n<p>However, the line\u2019s thickness is uniform no matter the force applied when writing. To draw a thicker line when the user applies greater pressure, use the Force property on the <strong>DrawLine<\/strong> method\u2019s touch parameter:<\/p>\n<pre class=\"EnlighterJSRAW\">\/\/2\r\ncontext.SetStrokeColor(color.CGColor);\r\nwidth = touch.Force &gt; 0 ? touch.Force * force : force;\r\ncontext.SetLineWidth(width);\r\ncontext.SetLineCap(CGLineCap.Round);<\/pre>\n<p><img decoding=\"async\" class=\"size-medium aligncenter\" src=\"https:\/\/i.imgur.com\/zpeEA1x.jpg\" alt=\"for_input\" width=\"567\" height=\"800\" \/><\/p>\n<p>Much better now!<\/p>\n<p>If you look at lines closely, you will see that the writing appears slightly notched and has sharp edges and points. This can happen when the Apple Pencil moves quickly on the surface and some of the touch events are lost.<\/p>\n<p>To smooth out the lines, use coalesced touches in <strong>TouchesMoved:<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\">\/\/ 2\r\nUIGraphics.BeginImageContextWithOptions(Bounds.Size, false, 0);\r\nvar context = UIGraphics.GetCurrentContext();\r\nImage?.Draw(Bounds);\r\nforeach (var t in evt?.GetCoalescedTouches(touch))\r\n{\r\n    DrawLine(context, t);\r\n}\r\nImage = UIGraphics.GetImageFromCurrentImageContext();<\/pre>\n<p>With this change, the writing looks smooth:<\/p>\n<p><img decoding=\"async\" class=\"size-medium aligncenter\" src=\"https:\/\/i.imgur.com\/16NuxQl.jpg\" alt=\"smooth\" width=\"658\" height=\"800\" \/><\/p>\n<h2>Wrapping up<\/h2>\n<p>It is possible to use <strong>UITouch.AltitudeAngle<\/strong> and <strong>UITouch.GetAzimuthAngle(View)<\/strong> to further refine the writing. <a href=\"https:\/\/developer.xamarin.com\/api\/type\/MonoTouch.UIKit.UITouch\/\">Check out Xamarin\u2019s UITouch documentation<\/a> and download the complete sample application from <a href=\"https:\/\/github.com\/prashantvc\/SignaturePad\">Github<\/a>.<\/p>\n<p><a href=\"https:\/\/forums.xamarin.com\/139209\/handling-input-from-apple-pencil\">Discuss this post on the Xamarin forums<\/a>.\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After months of contemplation before finally buying an Apple Pencil to go along with the iPad Pro, it turns out it is as magical as they say! This blog post describes how to use Xamarin.iOS and Visual Studio 2017 to build a signature pad app that works with Apple Pencil.<\/p>\n","protected":false},"author":558,"featured_media":40957,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2,303],"tags":[906,6],"class_list":["post-37989","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","category-ios","tag-apple-pencil","tag-ios"],"acf":[],"blog_post_summary":"<p>After months of contemplation before finally buying an Apple Pencil to go along with the iPad Pro, it turns out it is as magical as they say! This blog post describes how to use Xamarin.iOS and Visual Studio 2017 to build a signature pad app that works with Apple Pencil.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/37989","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/558"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=37989"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/37989\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/40957"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=37989"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=37989"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=37989"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}