将tap事件添加到IOS NSMutableAttributedString

时间:2013-03-18 18:00:00

标签: ios nsattributedstring

我有一个NSMutableAttributedString,例如“Bob喜欢你的照片”。

我想知道我是否可以为“Bob”和“picture”添加两个不同的点击事件。理想情况下,点击“Bob”将呈现具有Bob的配置文件的新视图控制器,并且点击“图片”将呈现具有该图片的新视图控制器。我可以使用NSMutableAttributedString吗?

2 个答案:

答案 0 :(得分:10)

您可以通过使用CoreText实现一个方法来实现此目的,该方法将检索用户选择/触摸的字符的索引。首先,使用CoreText,在自定义UIView子类中绘制属性字符串。覆盖drawRect:方法的示例:

- (void) drawRect:(CGRect)rect
{
    // Flip the coordinate system as CoreText's origin starts in the lower left corner
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(context, 0.0f, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0f, -1.0f);

    UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.bounds];
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge   CFAttributedStringRef)(_attributedString));

    if(textFrame != nil) {
        CFRelease(textFrame);
    }

    // Keep the text frame around.
    textFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path.CGPath, NULL);
    CFRetain(textFrame);

    CTFrameDraw(textFrame, context);
}

其次,创建一个询问文本的方法,以找到给定点的字符索引:

- (int) indexAtPoint:(CGPoint)point
{
    // Flip the point because the coordinate system is flipped.
    point = CGPointMake(point.x, CGRectGetMaxY(self.bounds) - point.y);
    NSArray *lines = (__bridge NSArray *) (CTFrameGetLines(textFrame));

    CGPoint origins[lines.count];
    CTFrameGetLineOrigins(textFrame, CFRangeMake(0, lines.count), origins);

    for(int i = 0; i < lines.count; i++) {
        if(point.y > origins[i].y) {
            CTLineRef line = (__bridge CTLineRef)([lines objectAtIndex:i]);
            return CTLineGetStringIndexForPosition(line, point);
        }
    }

    return 0;
}

最后,您可以覆盖touchesBegan:withEvent:方法以获取用户触摸位置并将其转换为字符索引或范围:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *t = [touches anyObject];
    CGPoint tp = [t locationInView:self];
    int index = [self indexAtPoint:tp];

    NSLog(@"Character touched : %d", index);
}

确保将CoreText包含在您的项目中并清理您保留的任何资源(如文本框架),因为该内存不是由ARC管理的。

答案 1 :(得分:1)

我处理它的方法是在NSString中使用标准UITextView。然后利用UITextInput协议方法firstRectForRange:。然后,您可以轻松地在该矩形中叠加一个不可见的UIButton并处理您想要采取的操作。