2

I have been working on wrapping my head around the TextKit work flow for Swift for a couple of days using some of the great questions and answers here among others.

I'm trying to find the bounding rect of a substring found in a label, if the user touches that perform an action, and if not do nothing. Currently, my bounding rect is off. Any feedback is greatly appreciated! Thank you for your time.

TableView Delegate cellForRowAtIndex:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(termsCell, forIndexPath: indexPath) as! TableViewCell

let linkRangeIndex = attributedString.string.rangeOfString("link")
let linkRange = attributedString.string.NSRangeFromRange(linkRangeIndex!)

attributedString.setAttributes(linkAttributes, range: linkRange)

cell.termsLabel.attributedText = attributedString
cell.termsLabel.userInteractionEnabled = true

textContainer.lineFragmentPadding = 0.0
textContainer.lineBreakMode = cell.termsLabel.lineBreakMode
textContainer.maximumNumberOfLines = cell.termsLabel.numberOfLines
let labelSize = cell.termsLabel.bounds.size
textContainer.size = labelSize

let tapGesture = UITapGestureRecognizer(target: self, action: "handleTapOnLabel:")
cell.termsLabel.addGestureRecognizer(tapGesture)

return cell

} }

Handle Taps on Label Method:

What I'm attempting to do is get the bounding rect box of "link" portion of the main string and check if the users touches are with in that box (then preform an action). However my bounding rect box is off. It fires (a print method for testing) when I click on the right side of "with"

@IBAction func handleTapOnLabel(tapGesture: UITapGestureRecognizer) {

let glyphPointer = NSRangePointer()

let linkRangeIndex = attributedString.string.rangeOfString("link")
let linkRange = attributedString.string.NSRangeFromRange(linkRangeIndex!)

let myString = "A string"
myString.NSRangeFromRange(linkRangeIndex!)

let glyphRange = layoutManager.characterRangeForGlyphRange(linkRange, actualGlyphRange: glyphPointer)
print("glyphRange: \(glyphRange)")

let glyphRect = layoutManager.boundingRectForGlyphRange(glyphRange, inTextContainer: textContainer)
print("glyphRect: \(glyphRect)")

let touchPoint = tapGesture.locationOfTouch(0, inView: cell?.textLabel)
print(touchPoint)

// need range of points for label

if CGRectContainsPoint(glyphRect, locationOfTouchInLabel) {
  print("I go home now")
} else {
  print("no")
}
}
}
Community
  • 1
  • 1
wambambizzle
  • 105
  • 7
  • 1
    "I'm trying to find the bounding rect of a substring found in a label" Not at all easy, since a label doesn't use TextKit (at least, not in a direct simple way). Basically, in trying to go down the TextKit road with a UILabel, you may have made a bad choice. If you want to analyze a click using TextKit, you would do better to use a UITextView, which is just a wrapper for TextKit, or even to draw the text yourself in a custom UIView, using TextKit. That makes it easy to detect where the tap is (in text terms). – matt Jan 26 '16 at 16:51
  • Here is a downloadable example project (with code from my book) in which we draw some text and the user can click on a word and we learn which word it is: https://github.com/mattneub/Programming-iOS-Book-Examples/tree/master/bk2ch10p543drawingWithTextKit/ch23p815attributedStringDrawing3 – matt Jan 26 '16 at 16:53
  • Even better, if you use a UITextView, just use the built-in link detection to deal with the click. The delegate can catch the click and do whatever you want. – matt Jan 26 '16 at 16:55
  • This will be used in a dynamically created tableview cell. I will give it a try setting it up this way. Looking into the sample project now. Thank you for the feedback! – wambambizzle Jan 26 '16 at 19:14
  • "This will be used in a dynamically created tableview cell" That really has nothing to do with it. :) – matt Jan 26 '16 at 19:42

0 Answers0