WWDC 2015 - Session 233 - iOS: https://developer.apple.com/videos/play/wwdc2015/233/?time=74
我可以找到Apple演示代码,但在我的生活中找不到[UIEvent predictedTouchesForTouch:]
上的任何实际文档。
它应该是iOS 9 API。这个API是否有效且尚未记录?我可以看到他们将它添加到Swift的API差异,但仍然没有文档。
答案 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