2013-12-05 2 views
0

оказывают кусок текста в NSAttributedString, уже отформатированы с атрибутами, которые делают правильно, в Multicolumn, многостраничный формат, используя TextKit следующим образом:каскадных NSAttributedString не оказывающие с правильным форматированием

NSUInteger lastRenderedGlyph = 0; 
CGFloat currentXOffset = 0; 

float width = screenDimensions.size.width; 
float height = screenDimensions.size.height; 

NSInteger columnCount = 1; 
NSInteger pageCount = 1; 
NSInteger counter = 1; 
self.storage = [[NSTextStorage alloc] initWithAttributedString:self.attrString]; 
self.manager = [[NSLayoutManager alloc] init]; 
[self.manager setAllowsNonContiguousLayout:YES]; 
[self.storage addLayoutManager:self.manager]; 

// loop through glyphs and layout text in multicolumn, multipage layout 
while (lastRenderedGlyph < self.manager.numberOfGlyphs) { 

    if (columnCount == 3) 
    { 
     columnCount = 1; 
     pageCount++; 
    } 
    float textViewFrame_y = 10.0; 
    float textViewFrame_height = height - 70.0; 

    CGRect textViewFrame = CGRectMake(currentXOffset, textViewFrame_y, 
             width/2, 
             textViewFrame_height); 
    CGSize columnSize = CGSizeMake(CGRectGetWidth(textViewFrame) - 20, 
            CGRectGetHeight(textViewFrame) - 10); 

    // Create text container for the column 
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:columnSize]; 

    // add text container to the layout manager 
    [self.manager addTextContainer:textContainer]; 

    // create the UITextView for this column   
    UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame 
               textContainer:textContainer]; 

    textView.font = [UIFont fontWithName:@"Georgia" size:currentFontSize];  
    textView.scrollEnabled = NO; 
    textView.editable = NO; 
    textView.dataDetectorTypes = UIDataDetectorTypeAll; 
    textView.delegate = self; 
    textView.selectable = YES; 

    // Add the UITextView to the scrollview/page 
    [self.scrollView addSubview:textView]; 

    // Increase the current offset so we know where to put the next column 
    currentXOffset += CGRectGetWidth(textViewFrame); 

    counter++; 
    columnCount ++; 

    // And find the index of the glyph we've just rendered 
    lastRenderedGlyph = NSMaxRange([self.manager glyphRangeForTextContainer:textView.textContainer]); 
} 

Перед делать это однако, мне нужно добавить два дополнительных приписываемые строки в существующую NSAttributedString (self.attrString в данном примере), следующим образом:

UIFont *font_title = [UIFont fontWithName:@"Georgia" size:defaultFontSize+title_delta]; 
NSDictionary *attributes_title = [NSDictionary dictionaryWithObject:font_title forKey:NSFontAttributeName]; 

UIFont *font_author = [UIFont fontWithName:@"Georgia" size:authorFontSize]; 
NSDictionary *attributes_author = [NSDictionary dictionaryWithObject:font_author forKey:NSFontAttributeName]; 

// title attributed string 
NSString *fullTitle = [NSString stringWithFormat:@"%@%@",@"Moby Dick",@"\n"]; 

NSMutableAttributedString *mainTitleAttributed = [[NSMutableAttributedString alloc] initWithString:fullTitle attributes:attributes_title]; 

// author attributed string 
NSString *fullAuthor = [NSString stringWithFormat:@"%@%@", @"Herman Melville", @"\n"]; 
NSMutableAttributedString *authorAttributed = [[NSMutableAttributedString alloc] initWithString:fullAuthor attributes:attributes_author]; 

// put it all together 
[self.attrString insertAttributedString:authorAttributed atIndex:0]; 
[self.attrString insertAttributedString:mainTitleAttributed atIndex:0]; 

Когда я просматриваю содержимое приписываемой строки, результаты, я получаю следующее:

Moby Dick {NSFont = "font-family: \" Georgia \ "; font-weight: normal; font-style: normal; font-size: 28,00pt ";} Herman Melville {NSFont =" font-family: \ "Georgia \"; font-weight: normal; font-style: normal; font-size: 12,00pt ";} Lorem ipsum dolor et { NSColor =" UIDeviceWhiteColorSpace 0 1 "; NSFont =" font-family: \ "Times New Roman \"; font-weight: normal; font-style: normal; размер шрифта: 12.00pt "; NSParagraphStyle =" Выравнивание 4, LineSpacing 0, ParagraphSpacing 12, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Вкладки (\ п 28L, \ n 56L, \ n 84L, \ n 112L, \ n
140L, \ n 168L, \ n 196L, \ n 224L, \ n 252L, \ n 280L, \ n
308L, \ n 336L \ п), DefaultTabInterval 36, блоки (нуль), списки (нуль), BaseWritingDirection -1, HyphenationFactor 0, TighteningFactor 0, HeaderLevel 0" ;} более Lorem Ipsum и т.д. и т.п ...

т.е. это выглядит как добавлены атрибуты правильно. Однако, когда это выполняется с помощью TextKit (см. Первый фрагмент кода), размер текста и другой шрифт объединенных текстовых компонентов (заголовок и автор в этом примере) не могут отображаться как таковые и просто получают назначенные одинаковые базовые атрибуты как следующий текст.

Если, вместо того чтобы использовать TextKit, создать единую UITextView и сделать NSAttributedString непосредственно в этой точке зрения (т.е. не используя NSLayoutManager, и т.д.), шрифт и размер различия в вставленных строк, приписываемых DO делают правильно.

Мой вопрос: почему добавленный текст не может правильно отображаться при использовании TextKit, но не при работе непосредственно с UITextView? Мне нужно работать с TextKit для поддержки многоколоночных и исключений.

ответ

0

Я не думаю, что ваша аттрибутная строка имеет соответствующие атрибуты, присвоенные различным фрагментам текстов. Попробуйте вместо использования insertAttributedString:atIndex использовать следующий подход:

  • Создать строку с заполнителями '{Title} {Author}' (к примеру) и назначить атрибуты этих заполнители
  • Заменить заполнители с различными простыми строками, используя (убедитесь, что вы делаете это в обратный порядок - первая замена Автор заполнитель, затем Название)

UPDATE: После дальнейшего обсуждения в комментариях, мы выяснили проблему с кодом.После присвоения атрибутной строки textView автор вызывал textView.font = ..., и это очищало все атрибуты.

+0

Просто уточните: вы предлагаете создать две отдельные атрибутные строки с текстом {title} и {author}, а затем вставить их в основную атрибутную строку, а затем заменить текст-заполнитель на replaceCharactersInRange? – user2709279

+0

Нет. Создайте одну главную присваиваемую строку (шаблон). Замените только заполнители обычными текстовыми значениями. – sha

+0

Поскольку я должен начать с существующей атрибутной строки, как мне вставить заполнители в основную атрибутированную строку, если не с помощью 'insertAttributedString'? – user2709279