0

NSAttributedString次のように TextKit を使用して、正しくレンダリングされる属性で既にフォーマットされているテキストのチャンクを複数列の複数ページのフォーマットにレンダリングします。

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この例では)属性付きの文字列を 2 つ追加する必要があります。

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: \"ジョージア\"; font-weight: normal; font-style: normal; font-size: 28.00pt";}Herman Melville{NSFont = " font-family: \"ジョージア\"; 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; font-size: 12.00pt"; NSParagraphStyle = "配置 4、LineSpacing 0、ParagraphSpacing 12、ParagraphSpacingBefore 0、HeadIndent 0、TailIndent 0、FirstLineHeadIndent 0、LineHeight 0/0、LineHeightMultiple 0、LineBreakMode 0、タブ (\n 28L、\n 56L、\n 84L、\ 112L、\n
140L、\n 168L、\n 196L、\n 224L、\n 252L、\n 280L、\n
308L、\n 336L\n)、DefaultTabInterval 36、ブロック (null)、リスト (null)、BaseWritingDirection -1、HyphenationFactor 0、TighteningFactor 0、HeaderLevel 0"; }more lorem ipsum など...

つまり、属性が正しく追加されたように見えます。ただし、これを TextKit を使用してレンダリングすると (コードの最初のチャンクを参照)、マージされたテキスト コンポーネント (この例ではタイトルと作成者) のテキスト サイズと異なるフォントがそのままレンダリングされず、単に同じ基本が割り当てられます。次のテキストとして属性。

TextKit を使用する代わりに、単一の UITextView を作成し、NSAttributedStringそのビューに直接レンダリングする場合 (つまりNSLayoutManager、 などを使用しない場合)、挿入された属性付き文字列のフォントとサイズの違いは正しくレンダリングされます。

私の質問: TextKit を使用すると、追加されたテキストが正しくレンダリングされないのはなぜですか? 複数列と除外パスをサポートするには、TextKit を使用する必要があります。

4

1 に答える 1

0

あなたの属性付き文字列には、さまざまなテキストのチャンクに割り当てられた適切な属性があるとは思いません。insertAttributedString:atIndex次のアプローチを使用する代わりに試してください。

  • '{Title} {Author}'たとえば、プレースホルダーを含む文字列を作成し、これらのプレースホルダーに属性を割り当てます
  • を使用して、プレースホルダーを別のプレーンな文字列に置き換えreplaceCharactersInRangeます (これを逆の順序で行うようにしてください - 最初に Author プレースホルダーを置き換え、次に Title を置き換えます)

更新:コメントでさらに議論した後、コードの問題を突き止めました。属性付きの文字列を作成者に割り当てた後、textView呼び出しが行われtextView.font = ...、これによりすべての属性が消去されました。

于 2013-12-05T02:26:05.907 に答える