在UITextView中使超链接可点击是很简单的。您只需在IB中的视图上设置“检测链接”复选框,它就会检测HTTP链接并将其转换为超链接。
然而,这仍然意味着用户看到的是“原始”链接。RTF文件和HTML都允许你设置一个用户可读的字符串,“后面”有一个链接。
将带属性的文本安装到文本视图(或UILabel或UITextField)是很容易的。但是,当带有属性的文本包含链接时,它是不可点击的。
是否有一种方法使用户可读的文本点击在UITextView, UILabel或UITextField?
在SO上的标记是不同的,但这里是大致的思想。我想要的是这样的文本:
这个变形是由Face Dancer生成的,点击在应用程序商店中查看。
我唯一能得到的是:
这个变形是由Face Dancer生成的,点击http://example.com/facedancer在应用商店中查看。
如果你想在UITextView中使用NSLinkAttributeName,那么你可以考虑使用AttributedTextView库。它是一个UITextView子类,它让处理这些变得很容易。更多信息请参见:https://github.com/evermeer/AttributedTextView
你可以让文本的任何部分像这样交互(其中textView1是一个UITextView IBoutlet):
textView1.attributer =
"1. ".red
.append("This is the first test. ").green
.append("Click on ").black
.append("evict.nl").makeInteract { _ in
UIApplication.shared.open(URL(string: "http://evict.nl")!, options: [:], completionHandler: { completed in })
}.underline
.append(" for testing links. ").black
.append("Next test").underline.makeInteract { _ in
print("NEXT")
}
.all.font(UIFont(name: "SourceSansPro-Regular", size: 16))
.setLinkColor(UIColor.purple)
为了处理标签和提及,你可以使用这样的代码:
textView1.attributer = "@test: What #hashtags do we have in @evermeer #AtributedTextView library"
.matchHashtags.underline
.matchMentions
.makeInteract { link in
UIApplication.shared.open(URL(string: "https://twitter.com\(link.replacingOccurrences(of: "@", with: ""))")!, options: [:], completionHandler: { completed in })
}
我需要继续使用一个纯的UILabel,所以从我的点击识别器称为这(这是基于malex的响应在这里:字符索引在触摸点UILabel)
UILabel* label = (UILabel*)gesture.view;
CGPoint tapLocation = [gesture locationInView:label];
// create attributed string with paragraph style from label
NSMutableAttributedString* attr = [label.attributedText mutableCopy];
NSMutableParagraphStyle* paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.alignment = label.textAlignment;
[attr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, label.attributedText.length)];
// init text storage
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attr];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
// init text container
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(label.frame.size.width, label.frame.size.height+100) ];
textContainer.lineFragmentPadding = 0;
textContainer.maximumNumberOfLines = label.numberOfLines;
textContainer.lineBreakMode = label.lineBreakMode;
[layoutManager addTextContainer:textContainer];
// find tapped character
NSUInteger characterIndex = [layoutManager characterIndexForPoint:tapLocation
inTextContainer:textContainer
fractionOfDistanceBetweenInsertionPoints:NULL];
// process link at tapped character
[attr enumerateAttributesInRange:NSMakeRange(characterIndex, 1)
options:0
usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
if (attrs[NSLinkAttributeName]) {
NSString* urlString = attrs[NSLinkAttributeName];
NSURL* url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
}
}];
Swift 3的例子,以检测对属性文本点击的动作
https://stackoverflow.com/a/44226491/5516830
let termsAndConditionsURL = TERMS_CONDITIONS_URL;
let privacyURL = PRIVACY_URL;
override func viewDidLoad() {
super.viewDidLoad()
self.txtView.delegate = self
let str = "By continuing, you accept the Terms of use and Privacy policy"
let attributedString = NSMutableAttributedString(string: str)
var foundRange = attributedString.mutableString.range(of: "Terms of use") //mention the parts of the attributed text you want to tap and get an custom action
attributedString.addAttribute(NSLinkAttributeName, value: termsAndConditionsURL, range: foundRange)
foundRange = attributedString.mutableString.range(of: "Privacy policy")
attributedString.addAttribute(NSLinkAttributeName, value: privacyURL, range: foundRange)
txtView.attributedText = attributedString
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "WebView") as! SKWebViewController
if (URL.absoluteString == termsAndConditionsURL) {
vc.strWebURL = TERMS_CONDITIONS_URL
self.navigationController?.pushViewController(vc, animated: true)
} else if (URL.absoluteString == privacyURL) {
vc.strWebURL = PRIVACY_URL
self.navigationController?.pushViewController(vc, animated: true)
}
return false
}
同样,你可以用shouldInteractWith URLUITextFieldDelegate方法添加任何你想要的动作。
干杯! !
使用NSMutableAttributedString。
NSMutableAttributedString * str = [[NSMutableAttributedString alloc] initWithString:@"Google"];
[str addAttribute: NSLinkAttributeName value: @"http://www.google.com" range: NSMakeRange(0, str.length)];
yourTextView.attributedText = str;
编辑:
这不是直接关于这个问题,只是澄清一下,UITextField和UILabel不支持打开url。如果你想使用UILabel链接,你可以检查TTTAttributedLabel。
此外,你应该设置你的UITextView的dataDetectorTypes值为UIDataDetectorTypeLink或UIDataDetectorTypeAll以在单击时打开url。或者你也可以按照评论中的建议使用委托方法。