From ce27f993e50e1193ba24e7478d87024c8eeee328 Mon Sep 17 00:00:00 2001 From: Tim Johnsen Date: Sun, 10 Feb 2019 16:41:42 -0800 Subject: [PATCH] Update UberSignature to support high fidelity input with the Apple Pencil. Documented here https://apple.co/2E32vNk and here https://apple.co/2GzmDrX. --- .../ObjC/UBSignatureDrawingViewController.m | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/Sources/ObjC/UBSignatureDrawingViewController.m b/Sources/ObjC/UBSignatureDrawingViewController.m index 47acad2..ca968e5 100644 --- a/Sources/ObjC/UBSignatureDrawingViewController.m +++ b/Sources/ObjC/UBSignatureDrawingViewController.m @@ -153,21 +153,44 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; - [self _updateModelWithTouches:touches endContinuousLine:YES]; + [self _updateModelWithTouches:touches event:event endContinuousLine:YES]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesMoved:touches withEvent:event]; - [self _updateModelWithTouches:touches endContinuousLine:NO]; + [self _updateModelWithTouches:touches event:event endContinuousLine:NO]; } #pragma mark - Private -- (void)_updateModelWithTouches:(NSSet *)touches endContinuousLine:(BOOL)endContinuousLine +- (void)_updateModelWithTouches:(NSSet *)touches event:(UIEvent *)event endContinuousLine:(BOOL)endContinuousLine { - CGPoint touchPoint = [self.class _touchPointFromTouches:touches]; + NSMutableSet *const coalescedTouches = [NSMutableSet new]; + for (UITouch *touch in touches) { + // Get high fidelity (i.e. paired Apple stylus) touches on devices that support it. + // https://apple.co/2E32vNk + [coalescedTouches addObjectsFromArray:[event coalescedTouchesForTouch:touch]]; + } + if (coalescedTouches.count > 0) { + static NSArray *descriptors = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + descriptors = @[[NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(timestamp)) ascending:YES]]; + }); + NSArray *const sortedCoalescedTouches = [coalescedTouches sortedArrayUsingDescriptors:descriptors]; + [sortedCoalescedTouches enumerateObjectsUsingBlock:^(UITouch * _Nonnull touch, NSUInteger idx, BOOL * _Nonnull stop) { + [self _updateModelWithTouch:touch usePreciseLocation:YES endContinuousLine:endContinuousLine && idx == sortedCoalescedTouches.count - 1]; + }]; + } else { + [self _updateModelWithTouch:[touches anyObject] usePreciseLocation:NO endContinuousLine:endContinuousLine]; + } +} + +- (void)_updateModelWithTouch:(UITouch *)touch usePreciseLocation:(BOOL)usePreciseLocation endContinuousLine:(BOOL)endContinuousLine +{ + CGPoint touchPoint = [self.class _touchPointFromTouch:touch usePreciseLocation:usePreciseLocation]; if (endContinuousLine) { [self.model asyncEndContinuousLine]; @@ -193,11 +216,18 @@ - (void)_updateViewFromModel #pragma mark - Helpers -+ (CGPoint)_touchPointFromTouches:(NSSet *)touches ++ (CGPoint)_touchPointFromTouch:(UITouch *)touch usePreciseLocation:(BOOL)usePreciseLocation { - UITouch *touch = [touches anyObject]; + CGPoint point; + if (usePreciseLocation) { + // Use precise location for touches captured with paired Apple styluses. + // https://apple.co/2GzmDrX + point = [touch preciseLocationInView:touch.view]; + } else { + point = [touch locationInView:touch.view]; + } - return [touch locationInView:touch.view]; + return point; } @end