4

我注意到 iOS 7 引入了与文本布局相关的新类,例如 NSLayoutManager、NSTextStorage 和 NSTextContainer。我如何使用这些来获取有关 NSString 上的自动换行的信息?

例如,假设我有一个很长的 NSString,我把它放在 UILabel 中。如果我在 UILabel 上启用多行,它将产生如下字符串:

The quick brown fox jumps
over the lazy dog.

这很好,但我无法访问代码中的换行符(例如,在jumps我希望它返回的单词之后\n或类似的东西之后)。我想知道换行符发生在哪些字符索引处。我知道我们可以使用 CoreText 来做到这一点,但是由于我们在 iOS 7 中有这些新类,我想知道我们可以如何使用它们。

4

2 回答 2

14

例子:

CGFloat maxWidth = 150;
NSAttributedString *s = 
    [[NSAttributedString alloc] 
        initWithString:@"The quick brown fox jumped over the lazy dog." 
        attributes:@{NSFontAttributeName:[UIFont fontWithName:@"GillSans" size:20]}];
NSTextContainer* tc = 
    [[NSTextContainer alloc] initWithSize:CGSizeMake(maxWidth,CGFLOAT_MAX)];
NSLayoutManager* lm = [NSLayoutManager new];
NSTextStorage* tm = [[NSTextStorage alloc] initWithAttributedString:s];
[tm addLayoutManager:lm];
[lm addTextContainer:tc];
[lm enumerateLineFragmentsForGlyphRange:NSMakeRange(0,lm.numberOfGlyphs) 
    usingBlock:^(CGRect rect, CGRect usedRect, 
                 NSTextContainer *textContainer, 
                 NSRange glyphRange, BOOL *stop) {
    NSRange r = [lm characterRangeForGlyphRange:glyphRange actualGlyphRange:nil];
    NSLog(@"%@", [s.string substringWithRange:r]);
}];
于 2013-10-26T05:25:46.103 回答
1

速译:

    guard let font1: UIFont = textView.font else { return }
    var lines: [String] = []

    let maxWidth: CGFloat = textView.frame.width
    let s: NSAttributedString = NSAttributedString.init(string: textView.text, attributes: [.font: font1])
    let tc: NSTextContainer = NSTextContainer.init(size: CGSize(width: maxWidth, height: CGFloat.greatestFiniteMagnitude))
    let lm: NSLayoutManager = NSLayoutManager.init()
    let tm: NSTextStorage = NSTextStorage.init(attributedString: s)
    tm.addLayoutManager(lm)
    lm.addTextContainer(tc)
    lm.enumerateLineFragments(forGlyphRange: NSRange(location: 0, length: lm.numberOfGlyphs)) { (rect: CGRect, usedRect: CGRect, textContainer: NSTextContainer, glyphRange: NSRange, Bool) in

        let r: NSRange = lm.characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil)

        let str = s as NSAttributedString

        let s2 = str.attributedSubstring(from: r)

        print(s2)

        lines.append(s2.string)

    }
于 2019-07-10T06:03:41.027 回答