Как разбить длинный NSString на страницы - PullRequest
12 голосов
/ 28 сентября 2010

У меня длинная строка NSString, которую я хочу отобразить на нескольких страницах.

Но для этого мне нужно выяснить, сколько текста на самом деле поместится на странице.

[NSString sizeWithFont: ...] Недостаточно, он просто скажет мне, вписывается ли текст в прямоугольник или нет, если нет, он будет молча обрезать строку, но не скажет, где она обрезана!

Мне нужно знать первое слово, которое не помещается на странице, поэтому я могу разбить строку и нарисовать эту часть на следующей странице.(и повтор)

Есть идеи, как решить эту проблему?

Единственная идея, которая у меня есть до сих пор, - это неоднократно вызывать sizeWithFont: constrainedToSize: вокруг точки в строке, где я угадываюбудет разрыв страницы и анализ результирующего прямоугольника, но он кажется громоздким и медленным, и я чувствую, что у меня могут возникнуть дополнительные проблемы с получением 100% -ной точности ... (из-за спусков и прочего)

ofc,он должен быть доступен в общедоступном iOS SDK

Ответ:

Фу, это была какая-то волосатая документация.Вот моя законченная функция в качестве примера, может быть, она кому-нибудь поможет, поскольку там не так много примеров основного текста для 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 Ответ

3 голосов
/ 04 октября 2010

Вам стоит заглянуть в CoreText, доступный с iOS 3.2. Документы довольно сложные и могут быть найдены здесь . По сути, вы создаете CTFramesetter и вызываете CTFramesetterSuggestFrameSizeWithConstraints. Затем вы найдете диапазон текста, который соответствует данному размеру CGSize.

...