Search code examples
swiftuitextviewnsmutableattributedstringswift5

Clickable link within NSMutableAttributedString needs to show another viewcontroller / storyboard


I have a UITextView and NSMutableAttributedString which has a clickable link. I need this to show another storyboard but not quite sure how I could do this.

What I have so far works for external links but not a storyboard. Any help would be appreciated.

Not sure if the below code is the best way to approach it or not?

class HomeViewController: UIViewController {

    @IBOutlet weak var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let attributedString = NSMutableAttributedString(string: "Already have an account? Log in")
        attributedString.addAttribute(.link, value: "", range: NSRange(location: 25, length: 6))

        textView.attributedText = attributedString

    }

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        UIApplication.shared.open(URL)

        return false
    }


}

EDIT

After NikR answer I've updated my code to the following but still no success. It's still loading Google.

class HomeViewController: UIViewController, UITextViewDelegate {

    @IBOutlet weak var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let attributedString = NSMutableAttributedString(string: "Already have an account? Log in")
        attributedString.addAttribute(.link, value: "https://google.com", range: NSRange(location: 25, length: 6))

        textView.attributedText = attributedString
        textView.isSelectable = true
        textView.isEditable = false

        textView.delegate = self

    }

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {

        let loginViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "loginViewController")
        show(loginViewController, sender: self)

        return true
    }


}

Solution

  • Yes it's the right way. But not call:

    UIApplication.shared.open(URL)
    

    Simply initiate your VC and show/present it:

    let vc = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateInitialViewController()
    show( vc, sender: self )
    

    And don't forget to:

    textView.delegate = self