如何在 Objective-C 中单击 UILabel 上的超链接打开视图控制器
How to open a view controller on click of hyperlink on UILabel in Objective-C
我必须在 UILabel
上通过 hyperlink 打开一个视图控制器。 This 对我来说只起到了一半的作用。根据我的项目要求,我无法使用 UITextView
。
以下代码在 UILabel
上创建一个 hyperlink 并检测 link 上的触摸,但我想打开一个视图控制器而不是 URL。
@property (weak, nonatomic) @IBOutlet UILabel *label;
NSLayoutManager *layoutManager;
NSTextContainer *textContainer;
NSTextStorage *textStorage;
在 UILabel
:
上创建 hyperlink
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"String with a link" attributes:nil];
NSRange linkRange = NSMakeRange(14, 4);
NSDictionary *linkAttributes = @{ NSForegroundColorAttributeName : [UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0],
NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle) };
[attributedString setAttributes:linkAttributes range:linkRange];
_label.attributedText = attributedString;
// 检测此 Hyperlink.
上的触摸
_label.userInteractionEnabled = YES;
[_label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapOnLabel:)]];
要找出点击的是 link,而不是标签的任何其他部分。
// 创建 NSLayoutManager、NSTextContainer 和 NSTextStorage 的实例
layoutManager = [[NSLayoutManager alloc] init];
textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
// 配置layoutManager、textStorage和textContainer
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
textContainer.lineFragmentPadding = 0.0;
textContainer.lineBreakMode = _label.lineBreakMode;
textContainer.maximumNumberOfLines =_label.numberOfLines;
// 每次标签更改其框架时,更新 textContainer 的大小:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
textContainer.size = self.label.bounds.size;
}
//检测点击是否正好在link:
- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGesture
{
CGPoint locationOfTouchInLabel = [tapGesture locationInView:tapGesture.view];
CGSize labelSize = tapGesture.view.bounds.size;
CGRect textBoundingBox = [layoutManager usedRectForTextContainer:textContainer];
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);
if (NSLocationInRange(indexOfCharacter, linkRange)) {
// Open an URL, or handle the tap on the link in any other way
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://whosebug.com/"]];
}
}
// 使用这个函数呈现newViewController
-(void)navigateToTATViewController{
TATViewController *tatVC = [[self getStoryboardWithStoryboardType: kListingStoryboard] instantiateViewControllerWithIdentifier: @"TATViewControllerID"];
[self.navigationController presentViewController: tatVC animated:true completion:nil];
}
所以基本上你需要更新行:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://whosebug.com/"]];
并将其替换为 [self navigateToTATViewController]
;
我必须在 UILabel
上通过 hyperlink 打开一个视图控制器。 This 对我来说只起到了一半的作用。根据我的项目要求,我无法使用 UITextView
。
以下代码在 UILabel
上创建一个 hyperlink 并检测 link 上的触摸,但我想打开一个视图控制器而不是 URL。
@property (weak, nonatomic) @IBOutlet UILabel *label;
NSLayoutManager *layoutManager;
NSTextContainer *textContainer;
NSTextStorage *textStorage;
在 UILabel
:
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"String with a link" attributes:nil];
NSRange linkRange = NSMakeRange(14, 4);
NSDictionary *linkAttributes = @{ NSForegroundColorAttributeName : [UIColor colorWithRed:0.05 green:0.4 blue:0.65 alpha:1.0],
NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle) };
[attributedString setAttributes:linkAttributes range:linkRange];
_label.attributedText = attributedString;
// 检测此 Hyperlink.
上的触摸_label.userInteractionEnabled = YES;
[_label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapOnLabel:)]];
要找出点击的是 link,而不是标签的任何其他部分。
// 创建 NSLayoutManager、NSTextContainer 和 NSTextStorage 的实例
layoutManager = [[NSLayoutManager alloc] init];
textContainer = [[NSTextContainer alloc] initWithSize:CGSizeZero];
textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString];
// 配置layoutManager、textStorage和textContainer
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
textContainer.lineFragmentPadding = 0.0;
textContainer.lineBreakMode = _label.lineBreakMode;
textContainer.maximumNumberOfLines =_label.numberOfLines;
// 每次标签更改其框架时,更新 textContainer 的大小:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
textContainer.size = self.label.bounds.size;
}
//检测点击是否正好在link:
- (void)handleTapOnLabel:(UITapGestureRecognizer *)tapGesture
{
CGPoint locationOfTouchInLabel = [tapGesture locationInView:tapGesture.view];
CGSize labelSize = tapGesture.view.bounds.size;
CGRect textBoundingBox = [layoutManager usedRectForTextContainer:textContainer];
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);
if (NSLocationInRange(indexOfCharacter, linkRange)) {
// Open an URL, or handle the tap on the link in any other way
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://whosebug.com/"]];
}
}
// 使用这个函数呈现newViewController
-(void)navigateToTATViewController{
TATViewController *tatVC = [[self getStoryboardWithStoryboardType: kListingStoryboard] instantiateViewControllerWithIdentifier: @"TATViewControllerID"];
[self.navigationController presentViewController: tatVC animated:true completion:nil];
}
所以基本上你需要更新行:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://whosebug.com/"]];
并将其替换为 [self navigateToTATViewController]
;