2012-03-11 78 views
2

我正在使用CoreText来布置自定义视图。对我来说,下一步是检测触摸事件/手势事件上的哪个单词被点击。我已经完成了这方面的研究,并发现如何自定义标签的URL来接收触摸 - 但没有通用的建议。有没有人知道如何做到这一点?如何检测使用CoreText触摸哪个单词

UPDATE:

这是我的drawRect内的代码:方法 self.attribString = [ASTRING拷贝];

​​3210

这里就是我试图处理触摸事件

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    CGPoint point = [touch locationInView:self]; 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CFArrayRef lines = CTFrameGetLines(frameRef); 
    for(CFIndex i = 0; i < CFArrayGetCount(lines); i++) 
    { 
     CTLineRef line = CFArrayGetValueAtIndex(lines, i); 
     CGRect lineBounds = CTLineGetImageBounds(line, context); 
     NSLog(@"Line %ld (%f, %f, %f, %f)", i, lineBounds.origin.x, lineBounds.origin.y, lineBounds.size.width, lineBounds.size.height); 
     NSLog(@"Point (%f, %f)", point.x, point.y); 
     if(CGRectContainsPoint(lineBounds, point)) 
     { 

似乎CTLineGetImageBounds返回一个错误的起点(大小似乎是正确的),这里是NSLog的“0号线的一个例子(0.562500,-0.281250,279.837891,17.753906)“。

+0

我应该补充说,所有的来源在价值上都非常相似。 – xizor 2012-03-12 15:03:43

回答

2

touchesEnded:withEvent:中没有“当前上下文”。你现在没有画画。所以你不能打电话CTLineGetImageBounds()有意义。

我相信这里最好的解决方案是使用CTFrameGetLineOrigins()找到正确的路线(通过检查与Y起源),然后用CTLineGetStringIndexForPosition()找到行内正确的字符(从point减去行原点之后)。这适用于运行整个视图的简单堆积线(例如您的)。

其他的解决方案:

  • 期间drawRect:计算所有线矩形和缓存。然后,您可以在touchesEnded:...中进行矩形检查。如果绘图不如敲击那么常见,这是一个非常好的解决方案。如果绘图比敲击更为常见,那么这是一个不好的方法。

  • 使用CTLineGetTypographicBounds()进行所有计算。这不需要图形上下文。你可以用它来计算矩形。

  • drawRect:用当前上下文生成一个CGLayer并将其存储在ivar中。然后使用CGLayer的上下文来计算CTLineGetImageBounds()。来自CGLayer的上下文将与您用于绘制的图形上下文“兼容”。

旁注:你为什么要调用drawRect:UIGraphicsPushContext(context);?您正在将当前上下文设置为当前上下文。这没有意义。而我没有看到相应的UIGraphicsPopContext()

+0

我还没有实现UIGraphicsPopContext() - 我只是暂时把UIGraphicsPushContext(context)放在那里试图获取CTLineGetImageBounds(),这样当我调用UIGraphicsGetCurrentContext()时我得到了上次使用的上下文。这只是一个临时工作。 – xizor 2012-03-12 22:19:22

+0

我尝试将代码添加到drawRect中:就像您所建议的那样,但我再次获得线条起源,这些线条起源彼此非常相似,如(228,16)和(222,22),当这些值与任何东西都不匹配时。 – xizor 2012-03-12 22:24:14

+0

试着抚摸你回来的盒子(CGContextStrokeRect)。这些听起来有些合理(不确定你的视图是什么样的)。 – 2012-03-12 23:41:17