gpt4 book ai didi

ios - 从 UITextView 和 NSLayoutManager 获取行信息

转载 作者:技术小花猫 更新时间:2023-10-29 10:38:55 24 4
gpt4 key购买 nike

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

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

我认为 NSLayoutManager 可以帮助我,但我对它的经验并不丰富。我已经想通了一些(我认为),但仍然需要一些帮助。

Apple 有一些示例代码 ( here ) 可以让我知道 TextView 中的行数:

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 上使用此方法计算直线矩形:

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

并且给定 lineRanges 我应该能够使用(通过找到包含字形索引的 lineRange 来计算一个点的行号:

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

那么剩下的就是,如何在给定行号的情况下获取一行的内容(作为 NSString)?

最佳答案

思考一个简单的解决方案,这里有一个小代码可以重现你需要的东西

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

请看属性:

self.ranges = ranges;
self.frames = frames;
self.numberOfLines = numberOfLines;

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

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

我建议您在以下委托(delegate)中添加分析调用:

- (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 - 从 UITextView 和 NSLayoutManager 获取行信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22807959/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com