使用 Swift 的 UILabel 中的 NSAttributedString 单击事件
NSAttributedString click event in UILabel using Swift
假设我有一个 AttributedString:“已有帐户?请登录!”。
我将这个字符串放在 UILabel 中。现在,当用户点击“登录!”时,当前 viewController 应该转到另一个 viewController 或者在点击登录时调用某些函数。
任何代码或建议都可以。
您可以将 tapGesture 应用于标签。
创建点击手势识别器:
let tapGesture = UITapGestureRecognizer(target: self, action: "YOUR_METHOD:")
向标签添加手势识别器:
YOUR_LABEL.addGestureRecognizer(tapGesture)
用这种方法执行你的任务:
func YOUR_METHOD(sender:UITapGestureRecognizer){
// Perform your operations here.
}
您需要使用 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
}
}
}
}
您可以将点击手势识别器添加到您的 label/view,或者您可以将带有自定义 URL 协议的 link 嵌入到您的属性字符串中,使用 UITextView,然后打开关于 link 检测。然后,您需要实现 UITextView 委托方法来响应 links.
我在 GitHub 上有一个名为 DatesInSwift (link) 的演示项目,它在 UITextView 中实现了可点击的 link。看一下 ViewController.swift
中的 UITextView
委托方法 textView(_:shouldInteractWithURL:inRange)
。这是告诉文本视图它应该响应 URL.
的方法
然后你必须实现一个 UIApplicationDelegate 方法来处理 URL。示例应用程序使用 application(_:openURL:sourceApplication:annotation)
,已在 iOS 9 中弃用。对于新开发,您应该改用 application(_:openURL:options:)
。
您还需要将 CFBundleURLTypes
/ CFBundleURLSchemes
条目添加到您的 info.plist 以注册自定义 URL 方案(如 myompany.myapp.loginURL
)单击嵌入式 URL 以调用您的应用程序的顺序。
如某些答案所述,无需使用单独的手势识别器。相反,您可以结合使用属性文本和 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
}
}
您可以使用文本视图代替标签来打开视图控制器或使子字符串可点击。
为要使其可点击的字符串创建一个属性
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
}
如果你想用标签做,点击查看How can I make a clickable link in an NSAttributedString?.
语言更新基于回答:)
Swift 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
}
}
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: "contact@abc.com")
interactableText.addAttribute(NSAttributedStringKey.font,
value: UIFont.systemFont(ofSize: 17),
range: NSRange(location: 0, length: interactableText.length))
interactableText.addAttribute(NSAttributedStringKey.link,
value: "contact@abc.com",
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
}
假设我有一个 AttributedString:“已有帐户?请登录!”。
我将这个字符串放在 UILabel 中。现在,当用户点击“登录!”时,当前 viewController 应该转到另一个 viewController 或者在点击登录时调用某些函数。
任何代码或建议都可以。
您可以将 tapGesture 应用于标签。
创建点击手势识别器:
let tapGesture = UITapGestureRecognizer(target: self, action: "YOUR_METHOD:")
向标签添加手势识别器:
YOUR_LABEL.addGestureRecognizer(tapGesture)
用这种方法执行你的任务:
func YOUR_METHOD(sender:UITapGestureRecognizer){
// Perform your operations here.
}
您需要使用 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
}
}
}
}
您可以将点击手势识别器添加到您的 label/view,或者您可以将带有自定义 URL 协议的 link 嵌入到您的属性字符串中,使用 UITextView,然后打开关于 link 检测。然后,您需要实现 UITextView 委托方法来响应 links.
我在 GitHub 上有一个名为 DatesInSwift (link) 的演示项目,它在 UITextView 中实现了可点击的 link。看一下 ViewController.swift
中的 UITextView
委托方法 textView(_:shouldInteractWithURL:inRange)
。这是告诉文本视图它应该响应 URL.
然后你必须实现一个 UIApplicationDelegate 方法来处理 URL。示例应用程序使用 application(_:openURL:sourceApplication:annotation)
,已在 iOS 9 中弃用。对于新开发,您应该改用 application(_:openURL:options:)
。
您还需要将 CFBundleURLTypes
/ CFBundleURLSchemes
条目添加到您的 info.plist 以注册自定义 URL 方案(如 myompany.myapp.loginURL
)单击嵌入式 URL 以调用您的应用程序的顺序。
如某些答案所述,无需使用单独的手势识别器。相反,您可以结合使用属性文本和 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
}
}
您可以使用文本视图代替标签来打开视图控制器或使子字符串可点击。
为要使其可点击的字符串创建一个属性
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 }
如果你想用标签做,点击查看How can I make a clickable link in an NSAttributedString?.
语言更新基于
Swift 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
}
}
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: "contact@abc.com")
interactableText.addAttribute(NSAttributedStringKey.font,
value: UIFont.systemFont(ofSize: 17),
range: NSRange(location: 0, length: interactableText.length))
interactableText.addAttribute(NSAttributedStringKey.link,
value: "contact@abc.com",
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
}