代码之家  ›  专栏  ›  技术社区  ›  jer

核心文本映射字符

  •  9
  • jer  · 技术社区  · 14 年前

    我有一些触摸处理程序,它对我在其中绘制了一些属性化文本的视图的点击做出响应。通过这个,我已经到了 CTRunRef (和关联行)以及运行中的glyph数。

    我不容易弄明白的是,我如何能得到这一系列的字形,并给出我的属性字符串,将其映射到字符串中的字符。

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

    任何帮助都将不胜感激。

    更新 :实际上,在StackOverflow之外的另一个人的建议下,我已经以不同的方式去做了。基本上我所做的就是设置一个自定义属性, @"MyAppLinkAddress" 在将字符串转换为属性化字符串时找到的URL值。这发生在我画线之前。因此,当tap事件发生时,我只检查该属性是否存在,如果存在,则调用我的委托方法,如果不存在,则忽略它。这是我现在想要的工作方式,但我会让这个问题再开放几天,如果有人能想出一个答案,我会很高兴地接受它,如果它是一个工作的解决方案,以便一些其他人可以在将来的某个时候发现这个信息是有用的。

    2 回复  |  直到 12 年前
        1
  •  7
  •   jer    14 年前

    // 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();
            }
    }
    
        2
  •  3
  •   mohsenr    12 年前

    CTLineGetStringIndexForPosition()