我有一个NSMutableAttributedString,比如“Bob喜欢你的图片”。将点击事件添加到IOS NSMutableAttributedString
我想知道如果我可以添加两个不同的点击事件“鲍勃”和“图片”。理想情况下,点击“Bob”会为Bob的配置文件提供一个新的视图控制器,点击“图片”会为该图片提供一个新的视图控制器。我可以用NSMutableAttributedString来做到这一点吗?
我有一个NSMutableAttributedString,比如“Bob喜欢你的图片”。将点击事件添加到IOS NSMutableAttributedString
我想知道如果我可以添加两个不同的点击事件“鲍勃”和“图片”。理想情况下,点击“Bob”会为Bob的配置文件提供一个新的视图控制器,点击“图片”会为该图片提供一个新的视图控制器。我可以用NSMutableAttributedString来做到这一点吗?
我会处理它的方式是在UITextView
中使用标准NSString
。然后利用UITextInput
协议方法firstRectForRange:
。然后,您可以轻松地在该矩形上覆盖一个隐形UIButton
并处理您想要采取的操作。
你可以通过使用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管理。
这对我来说太复杂了。但谢谢你的答案! – zhengwx 2013-03-18 23:48:07
这很容易做到。谢谢! – zhengwx 2013-03-18 23:47:18