CoreText映射字符

时间:2010-09-29 14:28:02

标签: iphone ipad core-text

我有一些触摸处理程序,它响应了一个视图的点击,我已经绘制了一些属性文本。通过这个,我已经到了我有一个CTRunRef(和相关行)以及该运行中的字形数。

我无法轻易弄清楚,我是如何拍摄这些字形的,并且,鉴于我的属性字符串,将其映射到字符串中的字符。

具体问题是我想知道用户在视图中点击了什么单词,因此我可以处理该单词是否为URL并触发自定义委托方法,以便我可以用它打开Web视图。我有所有可能的子串,我只是不知道如何映射用户点击特定子串的位置。

非常感谢任何帮助。

UPDATE :我实际上是以不同的方式完成了它,根据另一个人的建议离开stackoverflow。基本上我所做的就是设置一个自定义属性@"MyAppLinkAddress",其中包含我在将字符串转换为属性字符串时找到的URL的值。这是在我绘制字符串之前发生的。因此,当敲击事件发生时,我只检查该属性是否存在,如果存在,则调用我的委托方法,如果不存在,则忽略它。这是我现在喜欢的方式,但是我要打开这个问题多了几天,如果有人能拿出答案的话,我很高兴接受它,如果它是一个有效的解决方案,那么其他一些或许可以在将来的某个时候找到这些信息。

2 个答案:

答案 0 :(得分:7)

正如我在更新中所提到的,我选择了另一条路线。相反,我有想法在属性字符串中使用自定义属性来指定我的链接,因为无论如何我在创建时都有它。所以我做到了。然后在我的触摸处理程序中,当点击一个运行时,我检查该运行是否具有该属性,如果是,则用它来调用我的委托。从那里我很高兴加载带有该URL的webview。

编辑:下面是代码片段,解释了我在这个答案中所做的事情。享受。

// When creating the attribute on your text store. Assumes you have the URL already. 
// Filled in for convenience
NSRange urlRange = [tmpString rangeOfString:@"http://www.foo.com/"];
[self.textStore addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)[UIColor blueColor].CGColor range:urlRange];
[self.textStore addAttribute:@"CustomLinkAddress" value:urlString range:urlRange];

...然后

// Touch handling code — Uses gesture recognizers, not old school touch handling.
// This is just a dump of code actually in use, read through it, ask questions if you
// don't understand it. I'll do my best to put it in context.
- (void)receivedTap:(UITapGestureRecognizer*)tapRecognizer
{
        CGPoint point = [tapRecognizer locationInView:self];

        if(CGRectContainsPoint(textRect, point))
        {
                CGContextRef context = UIGraphicsGetCurrentContext();

                point.y = CGRectGetHeight(self.contentView.bounds) - kCellNameLabelHeight - point.y;

                CFArrayRef lines = CTFrameGetLines(ctframe);
                CFIndex lineCount = CFArrayGetCount(lines);
                CGPoint origins[lineCount];
                CTFrameGetLineOrigins(ctframe, CFRangeMake(0, 0), origins);
                for(CFIndex idx = 0; idx < lineCount; idx++)
                {
                        CTLineRef line = CFArrayGetValueAtIndex(lines, idx);
                        CGRect lineBounds = CTLineGetImageBounds(line, context);
                        lineBounds.origin.y += origins[idx].y;

                        if(CGRectContainsPoint(lineBounds, point))
                        {
                                CFArrayRef runs = CTLineGetGlyphRuns(line);
                                for(CFIndex j = 0; j < CFArrayGetCount(runs); j++)
                                {
                                        CTRunRef run = CFArrayGetValueAtIndex(runs, j);
                                        NSDictionary* attributes = (NSDictionary*)CTRunGetAttributes(run);
                                        NSString* urlString = [attributes objectForKey:@"CustomLinkAddress"];
                                        if(urlString && ![urlString isEqualToString:@""])
                                        {
                                                [self.delegate didReceiveURL:[NSURL URLWithString:urlString]];
                                                UIGraphicsPopContext();
                                                return;
                                        }
                                }
                        }
                }
                UIGraphicsPopContext();
        }
}

答案 1 :(得分:3)

找到分接的行后,您可以通过调用CTLineGetStringIndexForPosition()来索取字符串中的索引。没有必要访问个别运行。