[TIMOB-19667] iOS9.1: Support for Apple Pencil
| GitHub Issue | n/a |
|---|---|
| Type | New Feature |
| Priority | Critical |
| Status | Closed |
| Resolution | Fixed |
| Resolution Date | 2016-02-12T03:27:35.000+0000 |
| Affected Version/s | n/a |
| Fix Version/s | Release 5.2.0 |
| Components | iOS |
| Labels | applepencil, iOS9.1, notable, qe-5.2.0 |
| Reporter | Chee Kiat Ng |
| Assignee | Angel Petkov |
| Created | 2015-10-05T06:25:47.000+0000 |
| Updated | 2018-10-10T16:30:04.000+0000 |
Description
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITouch_Class/index.html#//apple_ref/occ/cl/UITouch
iOS 9.1 introduces APIs that help you use coalesced and predictive touches that can be produced by Apple Pencil on supported devices. Specifically, the UITouch class includes:
The preciseLocationInView: and precisePreviousLocationInView: methods, which give you the precise location for a touch (when available)
The altitudeAngle property and the azimuthAngleInView: and azimuthUnitVectorInView: methods, which help you determine the altitude and azimuth of the stylus
The estimatedProperties and updatedProperties properties, which help you prepare to update touches that are estimated
For an example of some ways to take advantage of these APIs in your app, see the sample project [TouchCanvas: Using UITouch efficiently and effectively](https://developer.apple.com/library/prerelease/ios/samplecode/TouchCanvas/Introduction/Intro.html#//apple_ref/doc/uid/TP40016561).
PR pending: https://github.com/appcelerator/titanium_mobile/pull/7419 Demo code :
//this sets the background color of the master UIView (when there are no windows/tab groups on it) var previousePos = 0; var listenerType = "Nothing"; var win = Titanium.UI.createWindow({ backgroundColor : "#FFFFFF" }); var bswitchingViews = false; var tab1 = Ti.UI.createTab({ window: win, title: 'Normal View' }); var view = Titanium.UI.createView({ borderRadius:10, backgroundColor:'blue', width:Ti.UI.FILL, height:Ti.UI.FILL }); var label1 = Ti.UI.createLabel({ text : 'Main Screen', accessibilityLabel : 'Label on first Scrollview', color : 'white' }); var button1 = Ti.UI.createButton({ title : 'Listener : '+ listenerType, color : 'White', top : -40, left : 5, width : 150, height : 150 }); var forceButton = Ti.UI.createButton({ title : 'Enable/Dissable', color : 'White', top : -40, right : 10, width : 180, height : 150 }); forceButton.addEventListener("singletap",function (e) { bswitchingViews = !bswitchingViews; label2.text = 'Enables/Dissables switching between views with force touch. Current status =' + bswitchingViews; }); var label2 = Ti.UI.createLabel({ text : 'Enables/Disables switching between views with force touch. Current status =' + bswitchingViews, accessibilityLabel : 'Label on first Scrollview', color : 'white', top : 10, right : 5, font: { fontSize:12 }, width : 150, height : 150 }); button1.addEventListener("touchend", function(e) { //printNewProperties(e,"Button:touchEnd"); switch (listenerType) { case "touchmove": listenerType = "touchstart"; button1.title = 'Listener : '+ listenerType; break; case "touchstart": listenerType = "touchend"; button1.title = 'Listener : '+ listenerType; break; case "touchend": listenerType = "touchmove"; button1.title = 'Listener : '+ listenerType; break; default: listenerType = "touchmove"; button1.title = 'Listener : '+ listenerType; } }); view.addEventListener("touchmove", function(e) { if (listenerType == "touchmove") { printNewProperties(e,"View: " + listenerType); } }); view.addEventListener("touchstart", function(e) { if (listenerType == "touchstart") { printNewProperties(e,"View: "+listenerType); } }); view.addEventListener("touchend", function(e) { if (listenerType == "touchend") { printNewProperties(e,"View: "+listenerType); } }); function printNewProperties(e, touchType) { Ti.API.info(touchType+":force "+e.force); var forceString = touchType+":force "+e.force; Ti.API.info(touchType+":maximumPossibleForce "+e.maximumPossibleForce); Ti.API.info(touchType+":altitudeAngle "+ e.altitudeAngle); Ti.API.info(touchType+":time stamp "+ e.timestamp); printToScreen(e); } /*Second Wndow and Second Tab*/ var win2 = Titanium.UI.createWindow({ backgroundColor : "#FFFFFF" }); var tab2 = Ti.UI.createTab({ window: win2, title: 'Table View' }); var justStuff = Ti.UI.createTableViewSection({ headerTitle: 'Items' }); justStuff.add(Ti.UI.createTableViewRow({ title: 'Arrow' })); justStuff.add(Ti.UI.createTableViewRow({ title: 'Bow'})); var justStuff2 = Ti.UI.createTableViewSection({ headerTitle: 'More Items' }); justStuff2.add(Ti.UI.createTableViewRow({ title: 'Bottle' })); justStuff2.add(Ti.UI.createTableViewRow({ title: 'Apple' })); var table = Ti.UI.createTableView({ data: [justStuff,justStuff2] }); table.addEventListener("touchmove", function(e) { if (listenerType == "touchmove") { printNewProperties(e,"Table: " + listenerType); } }); table.addEventListener("touchstart", function(e) { if (listenerType == "touchstart") { printNewProperties(e,"Table: "+listenerType); } }); table.addEventListener("touchend", function(e) { if (listenerType == "touchend") { printNewProperties(e,"Table: "+listenerType); } }); win2.add(table); var tabGroup = Ti.UI.createTabGroup({ tabs: [tab1, tab2] }); /*Window 3 and 4 for the longPress and Force Press*/ var win3 = Titanium.UI.createWindow({ backgroundColor : "Green" }); var win3View = Titanium.UI.createView({ borderRadius:10, backgroundColor:'Green', width:Ti.UI.FILL, height:Ti.UI.FILL }); var labelWin3 = Titanium.UI.createLabel({ text : 'Label for the longPress window', }); var win4 = Titanium.UI.createWindow({ backgroundColor : "Red" }); var win4View = Titanium.UI.createView({ borderRadius:10, backgroundColor:'Red', width:Ti.UI.FILL, height:Ti.UI.FILL }); var labelWin4 = Titanium.UI.createLabel({ text : 'Label for Force Touch', color : 'White' }); win3View.add(labelWin3); win3.add(win3View); view.addEventListener("longpress", function(e){ if (bswitchingViews == true) { win3.open(); } }); win4View.add(labelWin4); win4.add(win4View); view.addEventListener("touchmove", function(e){ if (e.force > 2 && bswitchingViews == true) { win4.open(); } }); //Return to Main Window win3View.addEventListener("singletap" , function(e){ win3.close(); }); win4View.addEventListener("singletap" , function(e){ win4.close(); }); /*Console within App*/ var textArea = Ti.UI.createTextArea({ borderWidth : 2, borderColor : '#bbb', borderRadius : 5, color : 'Red', font : {fontSize:10}, editable : false, textAlign : 'left', bottom : 0, height : 100, width : Ti.UI.FILL, opacity : 0.5 }); function printToScreen(values) { if (values.y > previousePos.y + 10 || values.y < previousePos.y -10 ||values.x > previousePos.x + 10 || values.x < previousePos.x -10) { textArea.value = textArea.value + "force: " + values.force +"\n"; previousePos = values; } if (previousePos == 0) { previousePos = values; } } view.add(button1); view.add(label1); view.add(label2); view.add(forceButton); view.add(textArea); win.add(view); tabGroup.open();PR approved!
When using the demo code on the iPad Pro, all touches including the pencil have an undefined force. Tested on: iPad Pro (9.1) Mac OSX El Capitan 10.11.2 Studio: 4.5.0.201602111338 Ti SDK: 5.2.0.v20160210114026 Appc NPM: 4.2.3-2 App CLI: 5.2.0-255 Xcode 7.2 Node v4.2.4 Reopening issue.
PR(Master): https://github.com/appcelerator/titanium_mobile/pull/7712 PR(5_2_X): https://github.com/appcelerator/titanium_mobile/pull/7711
PRs merged!
The PR seems to only implement part of the [attributes](https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITouch_Class/index.html#//apple_ref/doc/uid/TP40006785-CH3-SW13) The [source](https://github.com/AngelkPetkov/titanium_mobile/blob/3d2c5daa39ef146e808cb48e68d1aabc804f0327/iphone/Classes/TiUtils.m#L1148-L1170) has force, maximumPossibleForce, timestamp and altitudeAngel, but not azimuthAngleInView, azimuthUnitVectorInView, preciseLocationInView and precisePreviousLocationInView I'm asking because [~bimmel] did mention these missing ones in the release notes: https://wiki.appcelerator.org/display/~bimmel/Titanium+SDK+5.2.0+Beta+Release+Note#TitaniumSDK5.2.0BetaReleaseNote-NewiOS9.1Features [~apetkov] given short time, maybe create a ticket for the missing ones?
That line has been updated to the following: "Full coverage for Apple Pencil APIs including force, maximumPossibleForce, timestamp and altitudeAngle." and a note (to myself) added that these features will be documented in 5.2.1 per a conversation with Angel this morning.
Closing ticket as fixed. Verified that the following events/properties can be triggered on the iPad Pro with the pencil: * touchmove * touchstart * touchend * force * maximumPossibleForce * altitudeAngle Tested on: Appcelerator Studio, build: 4.5.0.201602170821 Appc CLI NPM: 4.2.3-2 Appc CLI Core: 5.2.0-269 Arrow: 1.7.27 SDK: 5.2.0.v20160218123934 Node: v4.2.4 OS: El Capitan (10.11.3) Xcode: 7.2 Device: ipad pro (9.2.1) with pencil