[英]NSLayoutManager characterIndexForPoint method failing on 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的配置參數(大小,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:
重載。 每當您更改標簽的文本時,都會重新創建TextStorage,看起來布局管理器根本不喜歡它。 重用textStorage並通過調用setAttributedString:
僅更改文本setAttributedString:
解決了該問題。
實際上,我很早以前就解決了這個問題:((我編輯了帖子,但忘了回答自己。對不起!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.