首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从UITextView和NSLayoutManager获取线路信息

从UITextView和NSLayoutManager获取线路信息
EN

Stack Overflow用户
提问于 2014-04-02 10:03:42
回答 1查看 3.4K关注 0票数 12

为了支持UIAccessibilityReadingContent协议,我需要UITextView来回答关于它的线路的问题。这些是我需要实现的协议的方法:

  • accessibilityLineNumberForPoint: <-提供了一个坐标,返回一个行号
  • accessibilityContentForLineNumber: <-返回给定行的文本
  • accessibilityFrameForLineNumber: <-给定行号,返回其帧
  • accessibilityPageContent <- -整个文本内容。我有。:)

我认为NSLayoutManager可以帮助我,但我对此没有那么丰富的经验。我已经想出了一些办法(我想),但仍然需要一些帮助。

苹果有一些示例代码(here),可以获得文本视图中的行数:

代码语言:javascript
复制
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上使用这种方法计算直线长度。

代码语言:javascript
复制
- (NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container

在给定lineRanges时,我应该能够使用以下方法(通过查找包含字形索引的lineRange )来计算点的行号:

代码语言:javascript
复制
- (NSUInteger)glyphIndexForPoint:(CGPoint)point inTextContainer:(NSTextContainer *)container fractionOfDistanceThroughGlyph:(CGFloat *)partialFraction

那么,剩下的是,如何获得行的内容(作为一个NSString),给定一个行号?

EN

回答 1

Stack Overflow用户

发布于 2015-04-28 02:46:16

在一个简单的解决方案中思考,这里有一个小代码,可以重现您所需的内容。

代码语言:javascript
复制
- (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(tmpRange);
    }
    self.ranges = ranges;
    self.frames = frames;
    self.numberOfLines = numberOfLines;
}

请看一看这些物业:

代码语言:javascript
复制
self.ranges = ranges;
self.frames = frames;
self.numberOfLines = numberOfLines;

可以在类中使用以下内容来创建此属性:

代码语言:javascript
复制
@property (nonatomic) NSInteger numberOfLines;
@property (strong, nonatomic) NSArray *ranges;
@property (strong, nonatomic) NSArray *frames;

我建议你在下列代表中增加分析电话:

代码语言:javascript
复制
- (void)textViewDidChange:(UITextView *)textView

例如,在分析之后,您可以得到正在执行的第2行的框架:self.frames1

或者获取第二行的文本:[textView.text substringWithRange:[self.ranges1 rangeValue]]

例如:

代码语言:javascript
复制
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中的所有帧,我认为您可以轻松地做另一件事,使用坐标来猜测行号。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22807959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档