I'd like to get the index for the tapped character on a UILabel. I've subclassed a UILabel. In my awakeFromNib() I have this:
layoutManager = NSLayoutManager()
textStorage = NSTextStorage(attributedString: self.attributedText)
textStorage.addLayoutManager(layoutManager)
textContainer = NSTextContainer(size: CGSizeMake(self.frame.size.width, self.frame.size.height))
textContainer.lineFragmentPadding = 0
textContainer.maximumNumberOfLines = self.numberOfLines
textContainer.lineBreakMode = self.lineBreakMode
textContainer.size = self.frame.size
layoutManager.addTextContainer(textContainer)
It is working how I want it to for the first 5 characters of the label, as in I tap the first character and in my touchesEnded I get an index of 0:
var touchedCharacterIndex = layoutManager.characterIndexForPoint(touch.locationInView(self), inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
But when I tap anywhere past the first four characters of the UILabel, I get either 4 or 0, which is incorrect.
Thanks,
Update
From a suggestion in the comments, I've added this:
func updateTextStorage() {
if let attributedText = self.attributedText {
textStorage = NSTextStorage(attributedString: attributedText)
}
textStorage?.addLayoutManager(layoutManager)
textContainer = NSTextContainer(size: CGSizeMake(self.frame.size.width, self.frame.size.height))
textContainer?.lineFragmentPadding = 7
textContainer?.maximumNumberOfLines = self.numberOfLines
textContainer?.lineBreakMode = self.lineBreakMode
textContainer?.size = self.bounds.size
layoutManager.addTextContainer(textContainer!)
layoutManager.textStorage = textStorage
}
I call this in layoutSubviews()
, awakFromNib
and the setters of bounds
, frame
, attributedText
and text
.
And it is now giving me some weird indexes, like if text length is 21, tapping the first letter gives me 6.
layoutSubviews()
and updatetextContainer
's size there. The label'sframe
is likely to change afterawakeFromNib()
. – Cassiodorus