0

NSAttributedString使用 TextKit 将 a 中的一大段文本(已经使用正确呈现的属性格式化)呈现为多列、多页格式,如下所示:

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]);
}

但是,在执行此操作之前,我需要将两个附加的属性字符串添加到现有的NSAttributedStringself.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 \"; 字体粗细:正常;字体样式:正常;字体大小:12.00pt"; }Lorem ipsum dolor et { NSColor = "UIDeviceWhiteColorSpace 0 1"; NSFont = " font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; font-size: 12.00pt"; NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 12, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n 28L,\n 56L,\n 84L,\ n 112L,\n
140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n
308L,\n 336L\n), DefaultTabInterval 36, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningFactor 0, HeaderLevel 0"; }more lorem ipsum 等等...

即看起来属性已正确添加。但是,当使用 TextKit 渲染时(参见第一段代码),合并文本组件(本示例中的标题和作者)的文本大小和不同字体无法如此渲染,而只是被分配了相同的基本属性如下文。

如果我没有使用 TextKit,而是创建了一个 UITextView 并将其NSAttributedString直接呈现到该视图中(即不使用NSLayoutManager等),则插入的属性字符串中的字体和大小差异会正确呈现。

我的问题:为什么添加的文本在使用 TextKit 时无法正确呈现,但在直接使用 UITextView 时却没有?我需要使用 TextKit 来支持它的多列和排除路径。

4

1 回答 1

0

我不认为您的属性字符串具有分配给不同文本块的适当属性。尝试而不是insertAttributedString:atIndex使用以下方法:

  • 创建一个带有占位符的字符串'{Title} {Author}'(例如)并将属性分配给这些占位符
  • 使用不同的纯字符串替换占位符replaceCharactersInRange(确保以相反的顺序执行此操作 - 首先替换作者占位符,然后是标题)

更新:在评论中进一步讨论后,我们发现了代码的问题。在将属性字符串分配给textView作者后调用textView.font = ...,这是清理所有属性。

于 2013-12-05T02:26:05.907 回答