从较长的NSString返回一个包含字的NSString

Nil*_*nch 11 xcode objective-c word-wrap nsstring ios

可能重复:
UITextView:获取带有换行信息的文本

我一直在寻找NSString库和众多库,以获取一个可以采用如下长字符串的函数:

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui.
Run Code Online (Sandbox Code Playgroud)

并与CGSize或浮点一起指示宽度和正在使用的字体,并返回一个字符串,其中包含\n符号和单词包装.

结果(大致):

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac\n
egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet.\n
 Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. \n
placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra.\n
 Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi.\n
 Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci,\n
 sagittis tempus lacus enim ac dui. 
Run Code Online (Sandbox Code Playgroud)

我已经知道UITextViews这样做了,但这没有用,因为我需要在原始的OpenGL环境中渲染文本,所以我没有使用常规的UI元素.

我知道这既存在于框架中,也存在于某个公共类中.我只是简单地找不到任何统一的处理方法.

我想它接近[NSString sizeWithFont:forWidth:lineBreakMode:],但我不需要大小,我需要字符串本身.

mat*_*att 9

实际上没有必要重新发明这个轮子,因为它正是文本引擎每次包装文本时为你做的.什么文本引擎?它是核心文本.如果您下拉到Core Text的级别并让CTFramesetter为您布置文本,您可以通过询问生成的CTLines来了解它在哪里放置换行符.

该文档将帮助您入门:

http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/CoreText_Programming/Operations/Operations.html

网上有很多很好的教程.

简单的例子:

NSString* s = @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
@"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
@"enim ad minim veniam, quis nostrud exercitation ullamco laboris "
@"nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor "
@"in reprehenderit in voluptate velit esse cillum dolore eu fugiat "
@"nulla pariatur. Excepteur sint occaecat cupidatat non proident, "
@"sunt in culpa qui officia deserunt mollit.";
NSAttributedString* text = [[NSAttributedString alloc] initWithString:s];

CTFramesetterRef fs =
CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)text);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0,0,200,100000));
CTFrameRef f = CTFramesetterCreateFrame(fs, CFRangeMake(0, 0), path, NULL);
CTFrameDraw(f, NULL);

NSArray* lines = (__bridge NSArray*)CTFrameGetLines(f);
for (id aLine in lines) {
    CTLineRef theLine = (__bridge CTLineRef)aLine;
    CFRange range = CTLineGetStringRange(theLine);
    NSLog(@"%ld %ld", range.location, range.length);
}
CGPathRelease(path);
CFRelease(f);
CFRelease(fs);
Run Code Online (Sandbox Code Playgroud)

正如您将看到的,输出显示了每行包装文本的范围.这不是你想要的那种东西吗?

  • 如果这是一个愚蠢的问题,请原谅我,因为我还没有机会研究它,但现在 iOS 7 有了 NSLayoutManager 和 NSTextStorage,我们可以做你上面做的同样的事情而不直接处理 CoreText 框架吗?例如,通过使用一些更高级别的框架来代替? (2认同)
  • 这根本不是一个愚蠢的问题,是的,我们可以!而且这更容易。布局管理器会很高兴地告诉您每个行片段的完整字形/文本。 (2认同)
  • 太棒了,谢谢你的信息。我将其作为一个单独的问题发布:[如何使用新的 iOS 7 API 获取自动换行信息?](http://stackoverflow.com/questions/19600372/how-do-i-get-word-wrap-information -使用新的ios-7-api) (2认同)