【发布时间】:2016-11-28 16:03:03
【问题描述】:
假设我有一个 AttributedString:“已经有一个帐户?登录!”。
我将这个字符串放在 UILabel 中。现在,当用户点击“登录!”时,当前的 viewController 应该转到另一个 viewController,或者在点击登录时应该调用一些函数。
任何代码或建议都可以。
【问题讨论】:
标签: ios swift uilabel nsattributedstring
假设我有一个 AttributedString:“已经有一个帐户?登录!”。
我将这个字符串放在 UILabel 中。现在,当用户点击“登录!”时,当前的 viewController 应该转到另一个 viewController,或者在点击登录时应该调用一些函数。
任何代码或建议都可以。
【问题讨论】:
标签: ios swift uilabel nsattributedstring
无需使用单独的手势识别器作为某些答案状态。相反,您可以将属性文本与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
}
}
【讨论】:
textView.delegate = self 给出错误 无法将类型“ViewController”的值分配给类型“UITextViewDelegate?”
UITextViewDelegate 添加到视图控制器中,就像我的代码的第一行一样:class ViewController: UIViewController, UITextViewDelegate {?
您可以使用文本视图代替标签来打开视图控制器或使子字符串可点击。
为要使其可点击的字符串创建一个属性
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的委托方法来实现对一个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?。
【讨论】:
基于@Lindsey Scott答案的语言更新:)
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
}
}
【讨论】:
您可以将点击手势识别器添加到您的标签/视图中,或者您可以将带有自定义 URL 协议的链接嵌入到属性字符串中,使用 UITextView 并打开链接检测。然后,您需要实现 UITextView 委托方法来响应链接。
我在 GitHub 上有一个名为 DatesInSwift(链接)的演示项目,它在 UITextView 中实现了可点击的链接。看看ViewController.swift 中的UITextView 委托方法textView(_:shouldInteractWithURL:inRange)。这就是告诉文本视图它应该响应 URL 的方法。
然后你必须实现一个 UIApplicationDelegate 方法来处理 URL。示例应用使用application(_:openURL:sourceApplication:annotation),它在iOS 9 中已被弃用。对于新开发,您应该改用application(_:openURL:options:)。
您还需要在 info.plist 中添加 CFBundleURLTypes / CFBundleURLSchemes 条目以注册自定义 URL 方案(如 myompany.myapp.loginURL),以便单击嵌入式 URL 来调用您的应用。
【讨论】:
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
}
【讨论】:
你需要使用 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
}
}
}
}
【讨论】:
UITextView 的版本,并自定义它看起来像UILabel。
NSLinkAttributeName,为什么还要使用轻击手势?
您可以将 tapGesture 应用于标签。
创建点击手势识别器:
let tapGesture = UITapGestureRecognizer(target: self, action: "YOUR_METHOD:")
为标签添加手势识别器:
YOUR_LABEL.addGestureRecognizer(tapGesture)
用这种方法执行你的任务:
func YOUR_METHOD(sender:UITapGestureRecognizer){
// Perform your operations here.
}
【讨论】:
YOUR_LABEL.userInteractionEnabled = true。