CoreText映射字符

jer*_*jer 9 iphone ipad core-text

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

我无法轻易弄清楚的是,我如何能够获取这些字形,并且,鉴于我的属性字符串,将其映射到字符串中的字符.

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

任何帮助将不胜感激.

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

jer*_*jer 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];
Run Code Online (Sandbox Code Playgroud)

然后...

// 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();
        }
}
Run Code Online (Sandbox Code Playgroud)