web-dev-qa-db-fra.com

Événement de clic NSAttributedString dans UILabel à l'aide de swift

Supposons que j'ai une chaîne attribuée: "Vous avez déjà un compte? Connectez-vous!". Je place cette chaîne dans UILabel. Désormais, lorsqu'un utilisateur clique sur "Se connecter!", Le viewController actuel doit aller vers un autre viewController ou une fonction doit être appelée en cliquant sur se connecter.

Tout code ou suggestion devrait convenir.

8
Rishu Agrawal

Il n'est pas nécessaire d'utiliser un identificateur de gestes distinct comme l'indiquent certaines des réponses. Au lieu de cela, vous pouvez utiliser le texte attribué en combinaison avec les UITextViewDelegatetextView:shouldInteractWithURL:inRange:interaction: méthode pour y parvenir, ex:

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
    }
}
14
Lyndsey Scott

Mise à jour de la langue basée sur @ Lindsey Scott réponse :)

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
    }
}
3

Au lieu de Label, vous pouvez utiliser textview pour ouvrir View Controller ou rendre la sous-chaîne cliquable

  1. créer un attribut pour la chaîne que vous souhaitez rendre cliquable

    let linkAttributes = [
        NSLinkAttributeName: NSURL(string: "https://www.Apple.com")!,
        NSForegroundColorAttributeName: UIColor.blue
        ] as [String : Any]
    
  2. Faites de votre chaîne une chaîne attribuée

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

    vous pouvez donner votre gamme personnalisée ici.

  3. Ajoutez du texte attribué à votre affichage de texte

    YourTextView.attributedText = attributedString 
    
  4. Ensuite, implémentez la méthode déléguée suivante de l'affichage de texte pour implémenter l'interaction pour l'URL

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
    // here write your code of navigation 
    return false 
    }
    
  5. Si vous voulez le faire avec label, cliquez ici ( Comment faire un lien cliquable dans une chaîne NSAttributedString pour a )

3
Jarvis The Avenger

Vous pouvez ajouter un identificateur de geste tactile à votre étiquette/vue, ou vous pouvez intégrer un lien avec un protocole d'URL personnalisé dans votre chaîne attribuée, utiliser un UITextView et activer la détection de lien. Vous devrez ensuite implémenter la méthode déléguée UITextView pour répondre aux liens.

ÉDITER:

J'ai un projet de démonstration appelé DatesInSwift (lien) sur Github qui implémente des liens cliquables dans un UITextView. Jetez un œil à la méthode déléguée UITextViewtextView(_:shouldInteractWithURL:inRange) dans ViewController.Swift. C'est la méthode qui indique à la vue texte qu'elle doit répondre à l'URL.

Ensuite, vous devez implémenter une méthode UIApplicationDelegate pour gérer l'URL. L'exemple d'application utilise application(_:openURL:sourceApplication:annotation), qui est obsolète dans iOS 9. Pour les nouveaux développements, vous devez utiliser application(_:openURL:options:) à la place.

Vous devrez également ajouter une entrée CFBundleURLTypes/CFBundleURLSchemes à votre info.plist pour enregistrer un schéma d'URL personnalisé (comme myompany.myapp.loginURL) Afin de cliquer sur une URL intégrée à invoquez votre application.

2
Duncan C