Mobile Apps

iOS 9 3D Touch Sample App

iOS 9 3D Touch Sample App

This new sample app demonstrates the new 3D Touch capabilities of the iPhone 6S. Titanium 5.1 implements Peek and Pop and Home Screen Quick Actions. The new force-properties available in touch-events will be added in a later release as well as support for the related Apple Pencil.

screenshots

Force Touch vs 3D Touch

Force Touch was introduced with the Apple Watch and has later been added to the MacBook and Magic Trackpad for OS X. Still, these devices use two different techniques and 3D Touch is yet another.

  • Apple provides little detail about how Force Touch for Apple Watch exactly works, but as a developer it is important that you do not have direct access to the touch events and have to implement Context Menus to which a touch is either firm or not. It was even rumored that the Apple Watch measures how the surface of your finger grows as you press with more force.
  • The Trackpads however have four force sensors and allow developers to monitor the exact pressure and acceleration in OS X.
  • The developer experience for 3D Touch on iPhone 6S and 6S Plus is similar to Force Touch on OS X, but the technique driving it is again different. The screen is now one big pressure sensor which can measure the exact pressure anywhere.

Why Apple uses two different names for three different techniques is a mystery. We can probably expect the 3D Touch technique to come to Apple Watch 2 and new Trackpads at which point Force Touch would no longer be used.

Running the Sample

At this moment, the iOS Simulator does not let you to simulate 3D Touch events. So to run and test the sample you will need an iPhone 6S to build to.

NOTE: There is a tweak available to simulate the Quick Actions in iOS Simulator.

Via Appcelerator Studio

  • Import it via Dashboard if available.
  • Or import it via File > Import… > Git > Git Repository as New Project
    • Select URI and enter:
      https://github.com/appcelerator-developer-relations/appc-sample-3dtouch
  • Select a device to build to via Run > Run As.

Via CLI

  1. Clone the repository:
    git clone https://github.com/appcelerator-developer-relations/appc-sample-ti500
  2. To run it with appc run first import it to the platform:
    appc new --import --no-services
  3. Build to device:
    [appc run | ti build] -p ios -T device

Quick Actions

Press firmly on the app icon to reveal the static Quick Actions or Application Shortcuts. Once you’ve used the app add and then view a picture, you will also see the dynamic shortcut:

shortcuts

Static shortcuts

Static shortcuts must be specified in Info.plist and work right after the app has installed. In Titanium you will add them to tiapp.xml under the ios/plist/dict element, but apart from that you can just follow the Apple Reference.

In the sample app we’ve added a Quick Action to select a picture from the device photo gallery to add to the app.

Instead of UIApplicationShortcutItemIconType you can also use UIApplicationShortcutItemIconFile to use a 35x35dp so-called Template Image. The title and subtitle can be localized by using a name you provide strings for via i18n/<language>/app.xml – not strings.xml.

NOTE: To use custom template icons the image must be in an asset catalog. This is an optional feature in 5.1.0 that can be enabled by <use-app-thinning>true</use-app-thinning> under the ios element in tiapp.xml.

NOTE: It is a known issue that to use a custom template icon for static shortcuts you need to find the corresponding hash of the image found under build/iphone/Assets.xcassets.

We’ll come back to how we handle the action later.

Dynamic shortcuts

Dynamic shortcuts are created via an instance of Ti.UI.iOS.ApplicationShortcuts, which means they will only be available once you have used these APIs and they can also be removed.

In our sample we create a dynamic shortcut for the last-viewed picture in the details controller. We first create an instance of the above API and then use addDynamicShortcut. The params are similar to the static shortcuts, with the exception of icon which can be either the path to a Template Icon or one of the Ti.UI.iOS.SHORTCUT_ICON_TYPE_* constants.

NOTE: As you can see, we first use Ti.UI.iOS.forceTouchSupported to test if the OS version and device actually support 3D Touch. The app might crash if you don’t!

When a picture gets deleted from the app we use the different APIs also demonstrated in the api controller to also remove the shortcut if it happened to be the last one we’ve viewed. You’ll find this code in the thumbnail and details controllers.

Handling Quick Actions

When the user taps a Quick Action, the Ti.App.iOS:shortcutitemclick event is fired. The payload includes all properties you have set static or dynamic shortcut except the icon. Simply use itemtype to identify the shortcut and act accordingly.

In our sample app we’re listening to the event in the pictures controller. For the dynamic details-shortcut you can see we’re using the custom userInfo payload to get the actual model ID of the last-viewed picture.

Peek & Pop

Press firmly on one of the thumbnails in the sample app to play with Peek and Pop. As you start applying more force the rest of the screen will blur, then a preview will appear and finally the details window will open. Swipe up while you Peek to reveal any quick actions available. As you use it more often you will get a feel for the amount of pressure needed to trigger Peek directly.

preview

PreviewContext

To add Peek & Pop to a individual view or a ListView, create an instance of Ti.UI.iOS.createPreviewContext and set it to the view’s previewContext property. When used in a ListView you need to listen to the PreviewContext’s peek event and update the view set to its preview property.

NOTE: TableView currently does not (fully) support Peek & Pop.

Sample

Use the top-left icon on the Pictures tab to switch between thumbnails that each individually have a preview context and a ListView where all items share a preview context.

For both views we create the previewContext in preview.xml. Awaiting Alloy support I create the PreviewContext in preview.xml using te ns attribute. Without it, <PreviewContext> would compile to Ti.UI.createPreviewContext() instead of Ti.UI.iOS.createPreviewContext(). In preview.js I manually set the preview view as well as the actions for the peek. In classic this would look like:

$.previewContext = Ti.UI.iOS.createPreviewContext({
    contentHeight: 400,
    preview: $.preview,
    actions: createActions()
});
$.previewContext.addEventListener('peek', onPeek);
$.previewContext.addEventListener('pop', onPop);
  • The preview showed during Peek is simply a Titanium view you assign to the preview property. Use the previewContext’s contentHeight property to enable rounded corners and not have the view take up all available height.
  • Listen to the peek event to update a shared preview when it is about to be displayed for a specific item. The event payload has the sectionIndex, itemIndex and optional itemId you need to do so.
  • To pop you add an event listener to the pop event. It has the same payload as peek. In our sample we just open the details view via the helper method exposed in the list controller.
  • Finally an array of Quick Actions can be assigned to the actions property. These can also be grouped and the sample demonstrates both, as well as the different styles available.

Credits

A special thanks to community member Ben Bahrenburg for his initial implementation of the Quick Actions. Appcelerator engineer Hans Knöchel implemented Peek and Pop and did the initial version of this sample.