NSLayoutManager characterIndexForPoint方法在ios9上失败
  我正在实现一个自定义UILabel链接点击支持。  为此,我有以下方法:一个初始化结构(仅调用一次),一个检测字符串中文本的确定范围内的点击次数: 
- (void) sharedInit {
    // Remember, this method is only called once
    self.layoutManager = [[NSLayoutManager alloc] init];
    self.textContainer = [[NSTextContainer alloc] initWithSize:self.frame.size];
    [self.layoutManager addTextContainer:self.textContainer];
    self.myGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
    self.textContainer.lineFragmentPadding = 0.0;
    self.textContainer.lineBreakMode = self.lineBreakMode;
    self.textContainer.maximumNumberOfLines = self.numberOfLines;
    self.textContainer.size = self.frame.size;
}
- (void) onTap:(UITapGestureRecognizer*) tapGesture {
    CGPoint location = [tapGesture locationInView:tapGesture.view];
    NSInteger index = [self.layoutManager characterIndexForPoint:locationOfTouchInLabel
                                                 inTextContainer:self.textContainer
                        fractionOfDistanceBetweenInsertionPoints:nil];
    NSLog(@"index of tapped character: %li", index);
    // ... and some more code to work with that index
}
- (void) setFrame:(CGRect)frame {
    [super setFrame:frame];
    self.textContainer.size = self.frame.size;
}
- (void) setAttributedText:(NSAttributedString *)attributedText {
    [super setAttributedText:attributedText];
    self.textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedText];
    [self.textStorage addLayoutManager:self.layoutManager];
}
- (void) setNumberOfLines:(NSInteger)numberOfLines {
    [super setNumberOfLines:numberOfLines];
    self.textContainer.maximumNumberOfLines = numberOfLines;
}
  这里的关键变量是index ( onTap: mehtod)。  该变量返回所点击字符的索引,以便我们可以使用它。  这与iOS 8完美无瑕,但对于iOS 9,我看到以下行为: 
  我在开发iOS 8的功能时遇到了类似的问题,并且我通过将maximumNumberOfLines的NSTextContainer设置为正确的值来解决此问题,如初始化中所见。  当运行onTap方法时,TextContainer的配置参数(size,maxNumOfLines等)是正确的。  我检查了文档(https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/NSTextContainer_Class_TextKit/index.html#//apple_ref/occ/instm/NSTextContainer/lineFragmentRectForProposedRect:atIndex:writingDirection :remainingRect :)在这个版本中显然没有什么改变,所以我很迷茫。  到目前为止,这看起来像一个iOS9的错误,但我不想放弃任何选项。  我也提供了一些解决方法,但如果可能的话,我想知道该方法正在发生什么。 
那么,有人知道发生了什么吗? 提前致谢...
编辑:
两件事情:
glyphIndex而不是charIndex ,到目前为止它返回的是相同的结果(用一行确定,用一行以上为零) firstUnlaidCharIndex等于0。  在工作正常的情况下(iOS8和iOS9只有一行),它会返回正确的值,即第一个超出界限的字符。 尝试使用与UILabel和CGFLOAT_MAX高度相同的宽度初始化NSTextContainer的大小
    self.textContainer.size = CGSizeMake(self.bounds.size.width, CGFLOAT_MAX);
  解决了!  看起来问题是setAttributedText: overload。  每次更改标签的文本时,都会重新创建TextStorage,看起来布局管理器根本就不喜欢这一点。  重用textStorage并通过调用setAttributedString:改变文本setAttributedString:解决了问题。 
事实上,我很久以前就解决了这个问题:(我编辑了这篇文章,但忘了回答自己,对不起!
链接地址: http://www.djcxy.com/p/81951.html上一篇: NSLayoutManager characterIndexForPoint method failing on ios9
