有什么方法可以将 UITextView 的内容检索为换行的行数组?
我可以用愚蠢的方式来做,用 sizeWithFont 逐字测量,看看它可能在哪里换行,但我希望那里有更聪明的方法?
干杯
有什么方法可以将 UITextView 的内容检索为换行的行数组?
我可以用愚蠢的方式来做,用 sizeWithFont 逐字测量,看看它可能在哪里换行,但我希望那里有更聪明的方法?
干杯
您可以使用 textviews 布局管理器来获取这些。但它可从 ios 7 获得。您可以使用布局管理器的方法 - ( enumerateLineFragmentsForGlyphRange:usingBlock: )
下面的代码打印结果如下所示:
_textView.text = @"abcdsakabsbdkjflk sadjlkasjdlk asjkdasdklj asdpaandjs bajkhdb hasdskjbnas kdbnkja sbnkasj dbkjasd kjk aj";
NSLog(@"%d", _textView.text.length); // length here is 104.
[_textView.layoutManager enumerateLineFragmentsForGlyphRange: NSMakeRange(0, 104) usingBlock: ^(CGRect rect, CGRect usedRect, NSTextContainer *textContainer, NSRange glyphRange, BOOL *stop) {
NSLog(@"rect %@ - usedRect %@ - glyphRange %d %d -", NSStringFromCGRect(rect), NSStringFromCGRect(usedRect), glyphRange.location, glyphRange.length);
}];
打印结果:
2013-12-17 12:48:40.250 testEmpty[675:a0b] rect {{0, 0}, {200, 13.8}} - usedRect {{0, 0}, {176.08398, 13.8}} - glyphRange 0 31 -
2013-12-17 12:48:40.251 testEmpty[675:a0b] rect {{0, 13.8}, {200, 13.8}} - usedRect {{0, 13.8}, {182.11328, 13.8}} - glyphRange 31 31 -
2013-12-17 12:48:40.251 testEmpty[675:a0b] rect {{0, 27.6}, {200, 13.8}} - usedRect {{0, 27.6}, {168.75977, 13.8}} - glyphRange 62 28 -
2013-12-17 12:48:40.252 testEmpty[675:a0b] rect {{0, 41.400002}, {200, 13.8}} - usedRect {{0, 41.400002}, {82.035156, 13.8}} - glyphRange 90 14 -
因此,在每个块运行中,您将获得该glyphRange.length
行中使用的字符串的 as 长度。
我想你可以使用attributeString。使用它,您可以为一系列字符或单词设置颜色。获取 textview 中文本的长度并执行 attributeString 工作
我是这样做的,它似乎足够快。
-(void) _printCharactersAndPositionsForLines:(UITextView*) textView{
NSString * text = textView.text;
if (text != nil){
float currentLineY = -1;
int currentLineIndex = -1;
for (int charIndex = 0; charIndex < [text length]; charIndex++){
UITextPosition *charTextPositionStart = [textView positionFromPosition:textView.beginningOfDocument offset:charIndex];
UITextPosition *charTextPositionEnd = [textView positionFromPosition:charTextPositionStart offset:+1];
UITextRange *range = [textView textRangeFromPosition:charTextPositionStart toPosition:charTextPositionEnd];
CGRect rectOfChar = [textView firstRectForRange:range];
if (rectOfChar.origin.y > currentLineY){
currentLineY = rectOfChar.origin.y;
currentLineIndex++;
// new line
NSLog(@"line [%i] starts with '%@' at character index %i",currentLineIndex,[text substringWithRange:NSMakeRange(charIndex, 1)],charIndex);
}
}
}
}
使用属性字符串,我做了这个函数:
extension NSAttributedString {
func lines(in size: CGSize) -> [NSAttributedString] {
let textStorage = NSTextStorage(attributedString: self)
let layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: size)
textContainer.lineFragmentPadding = 0.0
layoutManager.addTextContainer(textContainer)
var lines = [NSAttributedString]()
layoutManager.enumerateLineFragments(forGlyphRange: layoutManager.glyphRange(forBoundingRect: CGRect(origin: .zero, size: size), in: textContainer)) { (_, _, _, range, _) in
let charactersRange = layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: nil)
lines.append(self.attributedSubstring(from: charactersRange))
}
return lines
}
}
因此,例如,您可以像这样运行它:
NSAttributedString(string: "J'aime le fromage. Donnez moi du fromage. Munster, Reblochon, ...\n Ou bien du saucisson", attributes: [
.font: UIFont.systemFont(ofSize: 12, weight: .semibold)
]).lines(in: CGSize(width: 130, height: .max))
将输出
[“J'aime le fromage.”、“Donnez moi du”、“fromage. Munster”、“Reblochon, ...”、“Ou bien du saucisson”]