Group Group Group Group Group Group Group Group Group

Handling touches from Apple Pencil

#1

The force returned from the apple pencil is a value between zero and one. Is it possible to convert it to the actual force with unit Newton? Does Apple mention how to convert it?

#2

Overview :
UIKit reports touches from Apple Pencil in the same way it reports touches from the user’s fingers. Specifically, UIKit delivers a UITouch object containing the location of the touch in your app. However, a touch object originating from Apple Pencil contains additional information, including the azimuth and altitude of Apple Pencil and the amount of force recorded at its tip.

Because Apple Pencil is a separate device, there is a delay between the time Apple Pencil gathers altitude, azimuth, and force values and the time that those values are reported to your app. As a result, UIKit may provide estimated values for those properties initially, and then provide the real values at a later time.

When UIKit has only an estimate of a property’s value, it includes a flag in the estimatedPropertiesExpectingUpdates property of the corresponding UITouch object. When handling a touch event, check that property to determine if you need to update the touch information later.

When a touch object contains estimated properties, UIKit also provides a value in the estimationUpdateIndex property that you can use to identify the touch later. Use the value in the estimationUpdateIndex property as a key to a dictionary that you maintain. Set the value of that key to the app-specific object that you use to store the touch information. When UIKit later reports the real values, use the index to look up your app-specific object and replace the estimated values with the real values.

Tracking touches that need updates

var estimates : [NSNumber : StrokeSample]

func addSamples(for touches: [UITouch]) {
if let stroke = strokeCollection?.activeStroke {
for touch in touches {
if touch == touches.last {
let sample = StrokeSample(point: touch.location(in: self),
forceValue: touch.force)
stroke.add(sample: sample)
registerForEstimates(touch: touch, sample: sample)
} else {
let sample = StrokeSample(point: touch.location(in: self),
forceValue: touch.force, coalesced: true)
stroke.add(sample: sample)
registerForEstimates(touch: touch, sample: sample)
}
}
self.setNeedsDisplay()
}
}

func registerForEstimates(touch : UITouch, sample : StrokeSample) {
if touch.estimatedPropertiesExpectingUpdates.contains(.force) {
estimates[touch.estimationUpdateIndex!] = sample
}
}