【问题标题】:NSAttributedString click event in UILabel using Swift使用Swift的UILabel中的NSAttributedString单击事件
【发布时间】:2016-11-28 16:03:03
【问题描述】:

假设我有一个 AttributedString:“已经有一个帐户?登录!”。

我将这个字符串放在 UILabel 中。现在,当用户点击“登录!”时,当前的 viewController 应该转到另一个 viewController,或者在点击登录时应该调用一些函数。

任何代码或建议都可以。

【问题讨论】:

    标签: ios swift uilabel nsattributedstring


    【解决方案1】:

    无需使用单独的手势识别器作为某些答案状态。相反,您可以将属性文本与UITextViewDelegatetextView: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?”
    • @RishuAgrawal 您是否将UITextViewDelegate 添加到视图控制器中,就像我的代码的第一行一样:class ViewController: UIViewController, UITextViewDelegate {
    • 我如何识别如果有两个链接并基于点击如果我想应用不同的操作..
    【解决方案2】:

    您可以使用文本视图代替标签来打开视图控制器或使子字符串可点击。

    1. 为要使其可点击的字符串创建一个属性

      let linkAttributes = [
          NSLinkAttributeName: NSURL(string: "https://www.apple.com")!,
          NSForegroundColorAttributeName: UIColor.blue
          ] as [String : Any]
      
    2. 使您的字符串成为属性字符串

      let attributedString = NSMutableAttributedString(string:"My name is Jarvis")
      attributedString.setAttributes(linkAttributes, range: NSMakeRange(5, 10))
      

      您可以在此处提供自定义范围。

    3. 在你的文本视图中添加一个属性文本

      YourTextView.attributedText = attributedString
      
    4. 然后实现如下textview的委托方法来实现对一个URL的交互

      func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
          // Here write your code of navigation
          return false
      }
      
    5. 如果你想用标签来做,点击查看How can I make a clickable link in an NSAttributedString?

    【讨论】:

      【解决方案3】:

      基于@Lindsey Scott答案的语言更新:)

      斯威夫特 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
          }
      }
      

      【讨论】:

      • 解释一下。例如,(显着)差异是什么?
      【解决方案4】:

      您可以将点击手势识别器添加到您的标签/视图中,或者您可以将带有自定义 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 来调用您的应用。

      【讨论】:

        【解决方案5】:

        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
        }
        

        【讨论】:

          【解决方案6】:

          你需要使用 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
                      }
                  }
              }
          }
          

          【讨论】:

          • @RishuAgrawal:您可以禁用UITextView 的版本,并自定义它看起来像UILabel
          • 既然可以简单地使用NSLinkAttributeName,为什么还要使用轻击手势?
          • 你能解释一下如何使用它吗?
          • 查看我的答案的编辑。有很多步骤。
          【解决方案7】:

          您可以将 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
          • 但这是整个字符串的调用方法,而不仅仅是“登录!”
          • 然后只需使用两个标签,然后在登录标签上添加轻触即可。
          • @VishalSonawane :你说得对,但我希望使用单个标签。
          • 然后看看这个stackoverflow.com/questions/8811909/…,当你的词与登录匹配时执行你的操作(通过那个链接你会明白我的意思)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多