ios 使用swift在UILabel中的NSAttributedString点击事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38565603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NSAttributedString click event in UILabel using swift
提问by Rishu Agrawal
Suppose I have an AttributedString : "Already have an account? Sign in!". I am placing this String in UILabel. Now when a user clicks on "Sign in!", current viewController should go to another viewController or some function should be called while clicking on sign in.
假设我有一个 AttributedString :“已经有一个帐户?登录!”。我将此字符串放在 UILabel 中。现在,当用户单击“登录!”时,当前的 viewController 应该转到另一个 viewController 或者在单击登录时应该调用某些函数。
Any code or suggestion should be fine.
任何代码或建议都应该没问题。
回答by Lyndsey Scott
There's no need to use a separate gesture recognizer as some of the answers state. Instead, you can use attributed text in combination with the UITextViewDelegate
's textView:shouldInteractWithURL:inRange:interaction:
method to achieve this, ex:
正如某些答案所述,无需使用单独的手势识别器。相反,您可以将属性文本与UITextViewDelegate
的textView:shouldInteractWithURL:inRange:interaction:
方法结合使用来实现此目的,例如:
class ViewController: UIViewController, UITextViewDelegate {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
let text = NSMutableAttributedString(string: "Already have an account? ")
text.addAttribute(NSAttributedString.Key.font, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(0, text.length))
let selectablePart = NSMutableAttributedString(string: "Sign in!")
selectablePart.addAttribute(NSAttributedString.Key.font, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(0, selectablePart.length))
// Add an underline to indicate this portion of text is selectable (optional)
selectablePart.addAttribute(NSAttributedString.Key.underlineStyle, value: 1, range: NSMakeRange(0,selectablePart.length))
selectablePart.addAttribute(NSAttributedString.Key.underlineColor, value: UIColor.black, range: NSMakeRange(0, selectablePart.length))
// Add an NSLinkAttributeName with a value of an url or anything else
selectablePart.addAttribute(NSAttributedString.Key.link, value: "signin", range: NSMakeRange(0,selectablePart.length))
// Combine the non-selectable string with the selectable string
text.append(selectablePart)
// Center the text (optional)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.center
text.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, text.length))
// To set the link text color (optional)
textView.linkTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.black, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12)]
// Set the text view to contain the attributed text
textView.attributedText = text
// Disable editing, but enable selectable so that the link can be selected
textView.isEditable = false
textView.isSelectable = true
// Set the delegate in order to use textView(_:shouldInteractWithURL:inRange)
textView.delegate = self
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
// **Perform sign in action here**
return false
}
}
回答by Jarvis The Avenger
Instead of Label you can use textview to open View Controller or make substring clickable
您可以使用 textview 代替 Label 打开 View Controller 或使子字符串可点击
create attribute for string which you want to make clickable
let linkAttributes = [ NSLinkAttributeName: NSURL(string: "https://www.apple.com")!, NSForegroundColorAttributeName: UIColor.blue ] as [String : Any]
Make your string attributed string
let attributedString = NSMutableAttributedString(string:"My name is Jarvis") attributedString.setAttributes(linkAttributes, range: NSMakeRange(5, 10))
you can give your custom range here.
Add Attributed text to your textview
YourTextView.attributedText = attributedString
Then implement following delegate method of textview to implement interaction for Url
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool { // here write your code of navigation return false }
If you want to do it with label,click here (How to make a clickable link in an NSAttributedString for a)
为要使其可点击的字符串创建属性
let linkAttributes = [ NSLinkAttributeName: NSURL(string: "https://www.apple.com")!, NSForegroundColorAttributeName: UIColor.blue ] as [String : Any]
使您的字符串属性字符串
let attributedString = NSMutableAttributedString(string:"My name is Jarvis") attributedString.setAttributes(linkAttributes, range: NSMakeRange(5, 10))
您可以在此处提供自定义范围。
将属性文本添加到您的文本视图
YourTextView.attributedText = attributedString
然后实现如下textview的delegate方法来实现对Url的交互
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool { // here write your code of navigation return false }
如果你想用标签来做,点击这里(如何在一个 NSAttributedString 中制作一个可点击的链接)
回答by Guilherme Matuella
Language update based on @Lindsey Scottanswer :)
基于@Lindsey Scott回答的语言更新:)
Swift 4
斯威夫特 4
class ViewController: UIViewController, UITextViewDelegate {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
let text = NSMutableAttributedString(string: "Already have an account? ")
text.addAttribute(NSAttributedStringKey.font,
value: UIFont.systemFont(ofSize: 12),
range: NSRange(location: 0, length: text.length))
let interactableText = NSMutableAttributedString(string: "Sign in!")
interactableText.addAttribute(NSAttributedStringKey.font,
value: UIFont.systemFont(ofSize: 12),
range: NSRange(location: 0, length: interactableText.length))
// Adding the link interaction to the interactable text
interactableText.addAttribute(NSAttributedStringKey.link,
value: "SignInPseudoLink",
range: NSRange(location: 0, length: interactableText.length))
// Adding it all together
text.append(interactableText)
// Set the text view to contain the attributed text
textView.attributedText = text
// Disable editing, but enable selectable so that the link can be selected
textView.isEditable = false
textView.isSelectable = true
textView.delegate = self
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
//Code to the respective action
return false
}
}
回答by Duncan C
You can add a tap gesture recognizer's to your label/view, or you can embed a link with a custom URL protocol into your attributed string, use a UITextView, and turn on link detection. You would then need to implement the UITextView delegate method for responding to links.
您可以将点击手势识别器添加到您的标签/视图,或者您可以将带有自定义 URL 协议的链接嵌入到您的属性字符串中,使用 UITextView,并打开链接检测。然后,您需要实现 UITextView 委托方法来响应链接。
EDIT:
编辑:
I have a demo project called DatesInSwift(link) on Github that implements clickable links in a UITextView. Take a look at the UITextView
delegate method textView(_:shouldInteractWithURL:inRange)
in ViewController.swift
. That's the method that tells the text view that it should respond to the URL.
我在 Github 上有一个名为DatesInSwift(链接)的演示项目,它在 UITextView 中实现了可点击的链接。看看的UITextView
委托方法textView(_:shouldInteractWithURL:inRange)
在ViewController.swift
。这是告诉文本视图它应该响应 URL 的方法。
Then you have to implement a UIApplicationDelegate method to handle the URL. The sample app uses application(_:openURL:sourceApplication:annotation)
, which was deprecated in iOS 9. For new development you should use application(_:openURL:options:)
instead.
然后你必须实现一个 UIApplicationDelegate 方法来处理 URL。示例应用程序使用application(_:openURL:sourceApplication:annotation)
在 iOS 9 中已弃用的 。对于新开发,您应该application(_:openURL:options:)
改用。
You will also need to add a CFBundleURLTypes
/ CFBundleURLSchemes
entry to your info.plist to register a custom URL scheme (like myompany.myapp.loginURL
) in order for clicking on an embedded URL to invoke your app.
您还需要向info.plist添加一个CFBundleURLTypes
/CFBundleURLSchemes
条目以注册自定义 URL 方案(如myompany.myapp.loginURL
),以便单击嵌入的 URL 来调用您的应用程序。
回答by issam
You need to Use UITextView
你需要使用 UITextView
class ViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
let attribute:NSAttributedString = NSAttributedString(string: "Already have an account? Sign in!", attributes: ["Tag" : true])
textView.attributedText = attribute
let tap = UITapGestureRecognizer(target: self, action: #selector(self.textTapped(_:)))
tap.delegate = self
textView.userInteractionEnabled = true
textView.addGestureRecognizer(tap)
}
func textTapped(recognizer:UITapGestureRecognizer) {
let textView:UITextView = recognizer.view as! UITextView
// Location of the tap in text-container coordinates
let layoutManager = textView.layoutManager
var location:CGPoint = recognizer.locationInView(textView)
location.x -= textView.textContainerInset.left
location.y -= textView.textContainerInset.top
var distance:CGFloat?
// Find the character that's been tapped on
let characterIndex = layoutManager.characterIndexForPoint(location, inTextContainer: textView.textContainer, fractionOfDistanceBetweenInsertionPoints: &distance!)
if characterIndex < textView.textStorage.length{
var range:NSRange?
let value = textView.attributedText.attribute("Tag", atIndex: characterIndex, effectiveRange: &range!)
if value {
// add your code here
}
}
}
}
回答by Prashant Gaikwad
Swift 4.2 and Xcode 11Using TextView it's much easy
Swift 4.2 和 Xcode 11使用 TextView 非常简单
func setupContactUsInTextView() {
let text = NSMutableAttributedString(string: "Contact us at email ")
text.addAttribute(NSAttributedStringKey.font,
value: UIFont.systemFont(ofSize: 17),
range: NSRange(location: 0, length: text.length))
let interactableText = NSMutableAttributedString(string: "[email protected]")
interactableText.addAttribute(NSAttributedStringKey.font,
value: UIFont.systemFont(ofSize: 17),
range: NSRange(location: 0, length: interactableText.length))
interactableText.addAttribute(NSAttributedStringKey.link,
value: "[email protected]",
range: NSRange(location: 0, length: interactableText.length))
text.append(interactableText)
contactUsTextView.attributedText = text
contactUsTextView.textAlignment = .center
contactUsTextView.isEditable = false
contactUsTextView.isSelectable = true
contactUsTextView.delegate = self
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
print("open website here...")
return false
}
回答by Vishal Sonawane
You can apply tapGesture to the label.
您可以将 tapGesture 应用于标签。
Create tap gesture recognizer:
创建点击手势识别器:
let tapGesture = UITapGestureRecognizer(target: self, action: "YOUR_METHOD:")
Add gesture recognizer to label:
将手势识别器添加到标签:
YOUR_LABEL.addGestureRecognizer(tapGesture)
Perform your tasks in this method:
在此方法中执行您的任务:
func YOUR_METHOD(sender:UITapGestureRecognizer){
// Perform your operations here.
}