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:)))
textView.addGestureRecognizer(tap)
}
@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?