Как разделить длинный NSString на страницы
У меня длинный NSString, который я хочу отобразить на нескольких страницах.
Но для этого мне нужно выяснить, сколько текста будет действительно соответствовать на странице.
[NSString sizeWithFont:...] Недостаточно, он просто скажет мне, подходит ли текст в прямоугольнике или нет, если его нет, он будет молча усекать строку, но он не скажет мне, где он усечен!
Мне нужно знать первое слово, которое не помещается на странице, поэтому я могу разбить строку и нарисовать ее на следующей странице. (и повторить)
Есть идеи, как это решить?
Единственная идея, которую я до сих пор знаю, - это неоднократно вызывать sizeWithFont: constrainedToSize: вокруг точки в строке, где я предполагаю, что разрыв страницы будет, и проанализировать полученный результат, но он кажется громоздким и медленным, и я чувствую себя У меня могут быть дополнительные проблемы, получая его на 100% точным... (из-за descenders и еще чего-то.)
ofc, он должен быть доступен в общедоступном SDK для iOS
Ответ:
Фу, это была какая-то волосатая документация. Вот моя законченная функция в качестве примера, возможно, это поможет кому-то, поскольку там не так много конкретных текстовых примеров для iphone.
+ (NSArray*) findPageSplits:(NSString*)string size:(CGSize)size font:(UIFont*)font;
{
NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:32];
CTFontRef fnt = CTFontCreateWithName((CFStringRef)font.fontName, font.pointSize,NULL);
CFAttributedStringRef str = CFAttributedStringCreate(kCFAllocatorDefault,
(CFStringRef)string,
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:(id)fnt,kCTFontAttributeName,nil]);
CTFramesetterRef fs = CTFramesetterCreateWithAttributedString(str);
CFRange r = {0,0};
CFRange res = {0,0};
NSInteger str_len = [string length];
do {
CTFramesetterSuggestFrameSizeWithConstraints(fs,r, NULL, size, &res);
r.location += res.length;
[result addObject:[NSNumber numberWithInt:res.length]];
} while(r.location < str_len);
// NSLog(@"%@",result);
CFRelease(fs);
CFRelease(str);
CFRelease(fnt);
return result;
}
ВАЖНОЕ ПРИМЕЧАНИЕ:
Вы не можете использовать возвращаемый диапазон или размер с любыми классами UIKit или строковыми чертежами! Вы должны использовать его только с Core Text, например, создавая CTFrame и рисуя это.
Тонкие различия в таких вещах, как кернинг, не позволяют комбинировать функции Core Text с UIKit.
Кроме того, обратите внимание, что возвращаемый размер был признан ошибочным.
Ответы
Ответ 1
Вы должны заглянуть в CoreText, доступный с iOS 3.2. Документы довольно сложны и здесь можно найти здесь. В основном вы создаете CTFramesetter и вызываете CTFramesetterSuggestFrameSizeWithConstraints. Затем вы найдете диапазон текста, который соответствует заданному CGSize.