我正在使用CoreText来布局自定义视图。我的下一步是检测触摸事件/手势事件中的哪个单词被点击。我已经对此进行了研究,并建议如何自定义标记网址以接收触摸 - 但没有通用。有没有人知道如何做到这一点?
更新:
这是我的drawRect:方法中的代码 self.attribString = [aString copy];
CGContextRef context = UIGraphicsGetCurrentContext();
// Flip the coordinate system
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGMutablePathRef path = CGPathCreateMutable(); //1
CGPathAddRect(path, NULL, self.bounds );
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)aString); //3
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, [aString length]), path, NULL);
CTFrameDraw(frame, context); //4
UIGraphicsPushContext(context);
frameRef = frame;
CFRelease(path);
CFRelease(framesetter);
这是我尝试处理触摸事件的地方
- (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“Line 0(0.562500,-0.281250,279.837891,17.753906)”的一个例子。
答案 0 :(得分:2)
touchesEnded:withEvent:
中没有“当前上下文”。你现在还没有画画。所以你不能有意义地打电话给CTLineGetImageBounds()
。
我认为这里最好的解决方案是使用CTFrameGetLineOrigins()
找到正确的行(通过检查Y原点),然后使用CTLineGetStringIndexForPosition()
在行中找到正确的字符(扣除后)来自point
)的行。这适用于运行整个视图的简单堆叠线(例如您的)。
其他解决方案:
计算drawRect:
期间的所有直线矩形并缓存它们。然后你可以在touchesEnded:...
中进行矩形检查。如果绘图不像点击那么常见,这是一个非常好的解决方案。如果绘图比点击更常见,那么这是一个糟糕的方法。
使用CTLineGetTypographicBounds()
完成所有计算。这不需要图形上下文。您可以使用它来计算矩形。
在drawRect:
中生成具有当前上下文的CGLayer并将其存储在ivar中。然后使用CGLayer
中的上下文来计算CTLineGetImageBounds()
。 CGLayer
的上下文将与您用于绘制的图形上下文“兼容”。
旁注:您为什么在UIGraphicsPushContext(context);
中拨打drawRect:
?您正在将当前上下文设置为当前上下文。这没有意义。我没有看到相应的UIGraphicsPopContext()
。