从UITextView和NSLayoutManager获取行信息
为了支持UIAccessibilityReadingContent
协议,我需要我的UITextView来回答关于它的行的问题。 这些是我需要实现的协议的方法:
-
accessibilityLineNumberForPoint:
< – 提供了一个坐标,返回一个行号 -
accessibilityContentForLineNumber:
< – 返回给定行的文本 -
accessibilityFrameForLineNumber:
< – 给定一个行号,返回其框架 -
accessibilityPageContent
< – 整个文字内容。 我有。 🙂
我认为,NSLayoutManager可以帮助我,但我不是那种经验。 我想到了一些(我认为),但仍然需要一些帮助。
苹果有一些示例代码( 这里 )可以让我在文本视图中的行数:
NSLayoutManager *layoutManager = [textView layoutManager]; unsigned numberOfLines, index, numberOfGlyphs = [layoutManager numberOfGlyphs]; NSRange lineRange; for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){ (void) [layoutManager lineFragmentRectForGlyphAtIndex:index effectiveRange:&lineRange]; index = NSMaxRange(lineRange); }
我用上面的lineRange
来计算,我可以在NSLayoutManager
上使用这个方法来计算行rects:
- (NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container
并给lineRanges
我应该能够计算一个点使用(通过查找lineRange
包含字形索引的行号:
- (NSUInteger)glyphIndexForPoint:(CGPoint)point inTextContainer:(NSTextContainer *)container fractionOfDistanceThroughGlyph:(CGFloat *)partialFraction
所以剩下的是,如何得到一个行的内容(作为一个NSString
),给定一个行号?
在一个简单的解决scheme思考,这里是一个小代码,重现你所需要的
- (void)analyse:(UITextView *)textView { NSLayoutManager *layoutManager = [textView layoutManager]; NSString *string = textView.text; unsigned numberOfLines, index, stringLength = [string length]; NSMutableArray *ranges = [NSMutableArray new]; NSMutableArray *frames = [NSMutableArray new]; for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++) { NSRange tmprange; NSRange range = [string lineRangeForRange:NSMakeRange(index, 0)]; CGRect rect = [layoutManager lineFragmentRectForGlyphAtIndex:index effectiveRange:&tmprange]; [ranges addObject:[NSValue valueWithRange:range]]; [frames addObject:[NSValue valueWithCGRect:rect]]; index = NSMaxRange(range); } self.ranges = ranges; self.frames = frames; self.numberOfLines = numberOfLines; }
请看看属性:
self.ranges = ranges; self.frames = frames; self.numberOfLines = numberOfLines;
你可以在你的课堂中创build下面的属性:
@property (nonatomic) NSInteger numberOfLines; @property (strong, nonatomic) NSArray *ranges; @property (strong, nonatomic) NSArray *frames;
我build议你在下面的代理中添加分析调用:
- (void)textViewDidChange:(UITextView *)textView
在那里你可以例如分析得到第二行的帧刚刚做的: self.frames [1]
或者获取第二行的文本:[textView.text substringWithRange:[self.ranges [1] rangeValue]]
比如像这样:
if (self.numberOfLines > 1) { NSRange range = [self.ranges[1] rangeValue]; NSLog(@"2nd line = %@", [textView.text substringWithRange:range]); NSLog(@"2nd line frame = %@", self.frames[1]); }
拥有self.frames中的所有框架,我认为你可以轻松地做其他事情,用坐标猜测行号。
- 用于IOS的XMLparsing器SDK
- 以编程方式检查是否设置了密码锁
- 在iOS模拟器上显示GMSMarkers时发生GMSThreadException
- 实现自定义animation来显示iPad上的指定视图的模态视图
- NSLayoutManager:调用setLocation(_:forStartOfGlyphRange :)将禁用整个string中的字距?
- 无法下载并打开PDF文件,错误未能在ios中findPDF头
- cordova – 我可以上传国际音标来testing飞行出sdk?
- 如何区分推送通知的Android和IOS Firebase ID?
- 如何从FlutterViewController“推送”UIViewController