Search code examples
iosswiftuitextview

How to intercept link click in UITextView in iOS 17? UITextItemInteraction is deprecated


I need to intercept the click on an link using UITextView in iOS 17. I was using the delegate below, but UITextItemInteraction is deprecated.

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

How do I intercept the click on link in Swift now?

Thank you!


Solution

  • All of the UITextViewDelegate methods related to shouldInteractWith: have been deprecated as of iOS 17. They have been replaced with 4 new delegate methods that take a UITextItem parameter.

    Among those 4 are textView(_:primaryActionFor:defaultAction:).

    When you see a deprecation warning for using one of the old delegate methods, you can see the following:

    enter image description here

    Or if you are using code completion while trying to add one of the old deprecated methods you will see:

    enter image description here

    which points out two possible replacement delegate methods (though it references only part of the signature).

    Look for the 4 UITextItem related delegate methods in the documentation for UITextViewDelegate.

    The following should be a replacement for the code in your question:

    func textView(_ textView: UITextView, primaryActionFor textItem: UITextItem, defaultAction: UIAction) -> UIAction? {
        if case .link(let url) = textItem.content {
            print(url)
        }
    
        return nil
    }
    

    Or if you want to prevent the menu from appearing when the link is tapped, you might want the following:

    func textView(_ textView: UITextView, menuConfigurationFor textItem: UITextItem, defaultMenu: UIMenu) -> UITextItem.MenuConfiguration? {
        if case .link(let url) = textItem.content {
            print("menu \(url)")
            return nil // prevent menu
        }
    
        return .init(menu: defaultMenu) // show default menu
    }
    

    If your deployment target is iOS 16 or lower then you can keep using the older delegate methods. You should only need to update if your deployment target is iOS 17.0 or later.