从UITextView和NSLayoutManager获取行信息 [英] Get line information from UITextView and NSLayoutManager

查看:1351
本文介绍了从UITextView和NSLayoutManager获取行信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In order to support the UIAccessibilityReadingContent protocol, I need my UITextView to answer me questions about its lines. These are the methods of the protocol that I need to implement:


  • accessibilityLineNumberForPoint: < - 提供坐标,返回行号

  • accessibilityContentForLineNumber:< - 返回给定行的文本

  • accessibilityFrameForLineNumber:< - 给定行号,返回其框架

  • accessibilityPageContent < - 整个文本内容。我有。 :)

  • accessibilityLineNumberForPoint: <- Provided a coordinate, return a line number
  • accessibilityContentForLineNumber: <- Return the text of a given line
  • accessibilityFrameForLineNumber: <- Given a line number, return its frame
  • accessibilityPageContent <- The entire text content. That I have. :)

我认为NSLayoutManager可以帮助我,但我对它没有经验。我已经想到了一些(我认为),但仍需要一些帮助。

I figure that NSLayoutManager can help me, but I'm not that experienced with it. I've figured some of it out (I think), but still need some help.

Apple有一些示例代码(这里)可以获取文本视图中的行数:

Apple has some sample code (here) that can get me the number of lines in the text view:

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 上使用此方法计算行数:

I figure that with lineRangeabove, I can calculate the line rects using this method on NSLayoutManager:

- (NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container

给出 lineRanges 我应该能够计算一个点的行号(通过找到包含字形的 lineRange index:

And given lineRanges I should be able to calculate the line number for a point using (by finding the lineRange that contains the glyph index:

- (NSUInteger)glyphIndexForPoint:(CGPoint)point inTextContainer:(NSTextContainer *)container fractionOfDistanceThroughGlyph:(CGFloat *)partialFraction

剩下的就是,如何获取一行的内容( NSString ),给定一个行号?

So what remains is, how do I get the content of a line (as an NSString), given a line number?

推荐答案

思考一个简单的解决方案,这里是一个重现你需要的小代码

thinking in an easy solution, here is a small code that reproduce what you need

- (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;

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

You can have the following in your class to create this properties:

@property (nonatomic) NSInteger numberOfLines;
@property (strong, nonatomic) NSArray *ranges;
@property (strong, nonatomic) NSArray *frames;

我建议您在以下代理中添加分析调用:

I suggest you to add the analyse call inside the following delegate:

- (void)textViewDidChange:(UITextView *)textView

例如,你可以在分析后得到第二行的框架: self.frames [1]

There you can for example after analyse get the frame of the 2nd line just doing: self.frames[1]

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

Or getting the text of the second line doing: [textView.text substringWithRange:[self.ranges[1] rangeValue]]

For像这样的例子:

For example like this:

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 中的所有帧认为你可以轻松做另一件事,用坐标猜测行号。

Having all the frames in self.frames I think you can easily do the other thing, guess the line number using a coordinate.

这篇关于从UITextView和NSLayoutManager获取行信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆