UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

How to differentiate between two identically spelled words in UITextView?

Forums > iOS

In my storybook app, I have pages of static (uneditable) text that I display in a UITextView. Users can tap on any word to get more info about the word. I maintain a list of word information for all of the words in the app.

Currently, the word info lookup is accomplished with this method adapted from SO:

var textView = UITextView()

override func viewDidLoad() {
        let tap = UITapGestureRecognizer(target: self, action: #selector(tapResponse(recognizer:)))


 @objc func tapResponse(recognizer: UITapGestureRecognizer) {
        let location: CGPoint = recognizer.location(in: textView)
        let position: CGPoint = CGPoint(x: location.x, y: location.y)
        let tapPosition: UITextPosition = textView.closestPosition(to: position)!
        guard let wordRange: UITextRange = textView.tokenizer.rangeEnclosingPosition(tapPosition, with: UITextGranularity.word, inDirection: UITextDirection(rawValue: 1)) else {return}

        var tappedWord: String = textView.text(in: wordRange) ?? ""

        // safely unwrap the word to make sure it's currently in our list of words
        if let word = Word.returnWord(tappedWord) {
            delegate?.wordSelected(word: word)

Unfortunately, this isn't able to distinguish between two identically spelled but different words. For example: "She read everything there was to read." "Read" is used with two different tenses and pronounced two different ways, but my currently approach wouldn't be able to distinguish between them.

Conceptually, two approaches spring to mind, but I don't know a) if either are good, or b) how to accomplish either :/

Approach #1:

  • since the text in the app is static, for each chunk of text, maintain a list of ranges where an alternative lookup should be performed.

Relying on specific ranges seems error prone because there are both starting and ending values that could get messed up. Would also be a more complicated object to create / store.

Approach #2:

  • Enumerate the words in the text. Rather than use a range to look up a word, figure out what the index of the tapped word is. Maintain a list of indexes for each chunk of text and perform alternative lookups based on that.

This approach seems more complicated to implement, but easier to maintain. I have greater faith in my ability to specify indexes vs text ranges when it comes to doing lookups. Unlike approach one, rather than a custom object, this could probably be implemented with a dictionary.

Any advice on how to accomplish approach 1 or 2, or something even better?


Hacking with Swift is sponsored by Superwall

SPONSORED Superwall lets you build & test paywalls without shipping updates. Run experiments, offer sales, segment users, update locked features and more at the click of button. Best part? It's FREE for up to 250 conversions / mo and the Superwall team builds out 100% custom paywalls – free of charge.

Learn More

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.