【问题标题】:get UITextView contents as array of lines将 UITextView 内容作为行数组获取
【发布时间】:2013-12-17 04:19:42
【问题描述】:

有什么方法可以将 UITextView 的内容检索为换行的行数组?

我可以用愚蠢的方式来做,用 sizeWithFont 逐字测量,看看它可能在哪里换行,但我希望那里有更聪明的方法?

干杯

【问题讨论】:

  • 你为什么需要这样的东西。你需要它的目的是什么。
  • 我希望在 UITextViews 中使用不同颜色的 UIView 框来注释文本。
  • 同意 Charan Giri。您可以使用 IOS 的属性字符串来实现您想要的。您可以使用属性字符串轻松做到这一点。
  • 嗯,是的,我不知道这个功能。似乎是 ios6 以后的版本,不适用于我的特定项目。很高兴知道,但谢谢!

标签: ios uitextview sizewithfont


【解决方案1】:

您可以使用 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 作为该行中使用的字符串长度。

【讨论】:

  • 效果很好,谢谢!如果我想停止在 Swift 中循环,我会打电话给 stop.initialize(to: true)
【解决方案2】:

我猜你可以使用attributeString。使用它,您可以为一系列字符或单词设置颜色。获取textview中文本的长度并做attributeString工作

【讨论】:

    【解决方案3】:

    我是这样弄的,好像也够快了。

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

    【讨论】:

      【解决方案4】:

      使用属性字符串,我做了这个函数:

      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”]

      【讨论】:

        猜你喜欢
        • 2013-10-19
        • 2023-03-18
        • 2018-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多