ios 9.2 predictTouchesForTouch:没有文档

时间:2016-02-28 18:35:36

标签: ios

WWDC 2015 - Session 233 - iOS: https://developer.apple.com/videos/play/wwdc2015/233/?time=74

我可以找到Apple演示代码,但在我的生活中找不到[UIEvent predictedTouchesForTouch:]上的任何实际文档。

它应该是iOS 9 API。这个API是否有效且尚未记录?我可以看到他们将它添加到Swift的API差异,但仍然没有文档。

1 个答案:

答案 0 :(得分:2)

是的,预测触摸的文档(非常类似于合并触摸的文档)是微不足道的。此时(Xcode 7.2和7.3 Beta 4),我看到的唯一参考(在您参考的WWDC视频之外以及散布在网络上的其他演示文稿)位于标题中,其中描述了预测的触摸:

  

用于触摸事件的辅助UITouch数组,预计会针对给定的主触摸发生。这些预测可能与触摸时的实际行为不完全匹配,因此它们应被解释为估计值。

但它的工作原理正如你所引用的WWDC视频中描述的那样,包括Swift和Objective-C。

注意,您可能无法在模拟器上看到预测和合并的触摸,但如果您使用功能强大的设备,则会出现这种情况。我在使用iPhone 6+时偶尔会看到预测的触摸,但在iPad Pro上一直看到它们(如果你在iPad Pro上使用Apple Pencil,则更多)。

为了说明合并和预测的触摸,这是一个Objective-C演示:

@interface ViewController ()

@property (nonatomic, strong) UIBezierPath *path;
@property (nonatomic, weak) CAShapeLayer *pathLayer;
@property (nonatomic, weak) CAShapeLayer *predictedPathLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // set up layer for the main (non-predicted) path; line blue line

    CAShapeLayer *mainPathLayer = [CAShapeLayer layer];
    mainPathLayer.lineWidth = 1;
    mainPathLayer.strokeColor = [UIColor blueColor].CGColor;
    mainPathLayer.fillColor = [UIColor clearColor].CGColor;
    mainPathLayer.lineCap = kCALineCapRound;
    mainPathLayer.lineJoin = kCALineJoinRound;
    mainPathLayer.frame = self.view.layer.bounds;
    [self.view.layer addSublayer:mainPathLayer];
    self.pathLayer = mainPathLayer;

    // set up layer for the predicted path, if any; thicker red line (just so I can see it clearly)

    CAShapeLayer *predictedPathLayer = [CAShapeLayer layer];
    predictedPathLayer.lineWidth = 5;
    predictedPathLayer.strokeColor = [UIColor redColor].CGColor;
    predictedPathLayer.fillColor = [UIColor clearColor].CGColor;
    predictedPathLayer.lineCap = kCALineCapRound;
    predictedPathLayer.lineJoin = kCALineJoinRound;
    predictedPathLayer.frame = self.view.layer.bounds;
    [self.view.layer addSublayer:predictedPathLayer];
    self.predictedPathLayer = predictedPathLayer;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    self.path = [UIBezierPath bezierPath];
    [self.path moveToPoint:[touch locationInView:self.view]];
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];

    // handle coalesced touches

    NSArray<UITouch *> *coalescedTouches = [event coalescedTouchesForTouch:touch];
    for (UITouch *coalescedTouch in coalescedTouches) {
        location = [coalescedTouch locationInView:self.view];
        [self.path addLineToPoint:location];
    }

    self.pathLayer.path = self.path.CGPath;

    // now handle predicted touches

    UIBezierPath *predictedPath = [UIBezierPath bezierPath];
    [predictedPath moveToPoint:location];
    NSArray<UITouch *> *predictedTouches = [event predictedTouchesForTouch:touch];


    for (UITouch *predictedTouch in predictedTouches) {
        [predictedPath addLineToPoint:[predictedTouch locationInView:self.view]];
    }

    self.predictedPathLayer.path = predictedPath.CGPath;

    // for diagnostic purposes, let's log the count of each; do not do this in production app

    NSLog(@"%ld %ld", [coalescedTouches count], [predictedTouches count]);
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.predictedPathLayer.path = NULL; // discard any predicted path, because that's no longer valid
}

@end

如果您需要在9之前支持iOS版本,那么您也要检查respondsToSelector

Swift示例非常相似。请参阅此关于平滑曲线的无关帖子,其中说明了如何在Swift中使用预测(和合并)触摸:Drawing class drawing straight lines instead of curved lines