- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在这个问题(Create tap-able "links" in the NSAttributedString of a UILabel?)中学习了NAlexN的答案,并自己写了一个demo。但是,我很不走运地完成了演示。下面是我的代码:(大家可以直接复制下面的代码到新项目中进行测试)
#import "ViewController.h"
@interface ViewController ()
{
UILabel* label;
NSTextContainer *textContainer;
NSLayoutManager *layoutManager;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[super viewDidLoad];
label=[[UILabel alloc]initWithFrame:CGRectMake(15, 30, 350, 300)];
label.backgroundColor=[UIColor greenColor];
label.userInteractionEnabled = YES;
UITapGestureRecognizer* tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTapOnLabel:)];
[tap setNumberOfTapsRequired:1];
[label addGestureRecognizer:tap];
[self.view addSubview:label];
NSMutableAttributedString *attributedString =[[NSMutableAttributedString alloc] initWithString:@"String with a link" attributes:nil];
NSRange linkRange = NSMakeRange(14, 4); // for the word "link" in the string above
NSDictionary *linkAttributes = @{ NSForegroundColorAttributeName : [UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0],NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle) };
[attributedString setAttributes:linkAttributes range:linkRange];
// Assign attributedText to UILabel
label.attributedText = attributedString;
// Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
layoutManager = [[NSLayoutManager alloc] init];
textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
// Configure layoutManager and textStorage
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
// Configure textContainer
textContainer.lineFragmentPadding = 0.0;
textContainer.lineBreakMode = label.lineBreakMode;
textContainer.maximumNumberOfLines = label.numberOfLines;
}
//each time the label changes its frame, update textContainer's size:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
textContainer.size = label.bounds.size;
NSLog(@"textContainer.size=%@",NSStringFromCGSize(textContainer.size));
}
- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGesture
{
NSLog(@"Tap received");
CGPoint locationOfTouchInLabel = [tapGesture locationInView:tapGesture.view];
CGSize labelSize = tapGesture.view.bounds.size;
CGRect textBoundingBox = [layoutManager usedRectForTextContainer:textContainer];
NSLog(@"textBoundingBox=%@",NSStringFromCGRect(textBoundingBox));
CGPoint textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,(labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
CGPoint locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x,locationOfTouchInLabel.y - textContainerOffset.y);
NSInteger indexOfCharacter = [layoutManager characterIndexForPoint:locationOfTouchInTextContainer inTextContainer:textContainer fractionOfDistanceBetweenInsertionPoints:nil];
NSRange linkRange = NSMakeRange(14, 4); // it's better to save the range somewhere when it was originally used for marking link in attributed string
if (NSLocationInRange(indexOfCharacter, linkRange))
{
// Open an URL, or handle the tap on the link in any other way
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://stackoverflow.com/"]];
NSLog(@" Link was taped ");
}
}
@end
运行结果为:
2016-03-11 10:58:04.457 [13451:1007618] textContainer.size={350, 300}
2016-03-11 10:58:07.968 [13451:1007618] Tap received
2016-03-11 10:58:07.969 [13451:1007618] textBoundingBox={{0, 0}, {0, 0}}
从运行结果来看,layoutManager似乎没有起作用。我不明白为什么,也许我以错误的方式使用了 layoutManager。任何机构都可以帮助解决这个问题。非常感谢!
P.S:此演示旨在在 UILabel 的 NSAttributedText 中创建可点击的 url 链接。
最佳答案
(OP 晚了五年,但这可能对某些人仍然有帮助。)
问题可能是因为 textBoundingBox 的矩形高度和宽度均为 0。尝试强制 layoutManager 预先正确布局文本,例如
[layoutManager ensureLayoutForGlyphRange:NSMakeRange(0, attributedString.length)];
关于ios - 为什么我无法通过使用 "usedRectForTextContainer"获取 textContainer 的 rect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35931789/
我试图通过以下过程计算 NSTextView 内容在设定宽度下所需的最小高度(其中 self 是 的实例NSTextView): let currentWidth = self.frame.width
我正在尝试使用以下代码获取在给定文本容器中显示文本所需的矩形大小: s = [manager usedRectForTextContainer:container].size; 我希望文本是多行的,但
我在这个问题(Create tap-able "links" in the NSAttributedString of a UILabel?)中学习了NAlexN的答案,并自己写了一个demo。但是,
我是一名优秀的程序员,十分优秀!