3

I'm trying to build a UITextView in iOS8 that recognizes taps on specific words, specifically words preceded by the "#" and "@ symbols"

I first tried the following method in a subclass of UITextView:

var point = tapGesture.locationInView(self)
var position = closestPositionToPoint(point)
let range = tokenizer.rangeEnclosingPosition(position, withGranularity: .Word, inDirection: 1)
let word = textInRange(range)
println(word!)

However, clicking on a word in a text view prints the word, but will leave out the "#" and "@", I believe this to be from the .Word granularity not recognizing special characters. I came up with a work around that uses attributed text to identify the prefixed special character.

var point = tapGesture.locationInView(self)
var position = closestPositionToPoint(point)
let range = tokenizer.rangeEnclosingPosition(position, withGranularity: .Word, inDirection: 1)

if range != nil {
  let location = offsetFromPosition(beginningOfDocument, toPosition: range!.start)
  let length = offsetFromPosition(range!.start, toPosition: range!.end)

  let attrRange = NSMakeRange(location, length)

  let attrText = attributedText.attributedSubstringFromRange(attrRange)


  let word = attributedText.attributedSubstringFromRange(attrRange)

  let isHashtag: AnyObject? = word.attribute("Hashtag", atIndex: 0, longestEffectiveRange: nil, inRange: NSMakeRange(0, word.length))
  let isAtMention: AnyObject? = word.attribute("Mention", atIndex: 0, longestEffectiveRange: nil, inRange: NSMakeRange(0, word.length))
  if isHashtag != nil {
    println("#\(word.string)")
  } else if isAtMention != nil {
    println("@\(word.string)")
  }
}

And this works pretty well, but tapping on the special character will not print out the word. Does anyone have possible solution to this problem? Is there a different way to identify tapped words without using rangeEnclosingPosition?

kohlerjp
  • 31
  • 2
  • Well # is obviously not a word so it is not returned. What happens if you try UITextGranularityCharacter (.Character) instead? If that works you'd just use a regular expression to filter every word out that is not prefixed by a # – edwardmp Nov 21 '14 at 18:29
  • It is identifiable with (.Character), but that doesn't really help identify the word it is attached to. – kohlerjp Nov 21 '14 at 18:34
  • Can you give an example of what is the full sentence and what is returned, and where you approximately tap? – edwardmp Nov 21 '14 at 18:35
  • If the sentence is: This is my #dog @sam. If I click on the "d", "o", or "g", I will return "dog" for the first method, and "#dog" for the second method. However, clicking tapping the "#" will not return anything for either method – kohlerjp Nov 21 '14 at 18:38
  • I'm reading here that it should work, but this may be a bug in iOS: http://stackoverflow.com/questions/18704692/detect-character-tapped-in-uitextview. Can you try running on another iOS version and see what happens? – edwardmp Nov 21 '14 at 18:43
  • See also [Detecting taps on attributed text in a UITextView in iOS](http://stackoverflow.com/a/32262426/3681880) – Suragch Jan 22 '16 at 04:57

0 Answers0