Search code examples
iosobjective-cparsingpdfcore-text

How to create two text columns in PDF?


The problem is to create two text columns in PDF like this: two independent text columns For generating PDF I use Apple's guide "Drawing and Printing Guide for iOS", two columns I create with tabs:

NSArray *stringList =
    @[
      @[string1, string2],
      @[@"", string4],
      @[string5, string6],
      @[string7, string8]
    ];

    resultString = [[NSMutableAttributedString alloc] init];
    for (NSArray *row in stringList) {
        int i = 0;
        NSMutableAttributedString *subResult = [[NSMutableAttributedString alloc] init];
        NSMutableArray *tabs = @[].mutableCopy;
        NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
        for (NSString *tempString in row) {
            NSTextTab *tab = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:200 options:nil];
            if ([tempString isKindOfClass:[NSAttributedString class]]) {
                [subResult appendAttributedString:(NSAttributedString *)tempString];
                [subResult appendAttributedString:[[NSAttributedString alloc] initWithString:@"\t"]];
            } else {
                [subResult appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@\t", tempString]]];
            }
            [tabs addObject:tab];
            i++;
        }
        [subResult appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
        [style setTabStops:tabs];
        [subResult addAttribute:NSParagraphStyleAttributeName
                          value:style
                          range:NSMakeRange(0, subResult.length)];
        [resultString appendAttributedString:subResult];
    }

As output I get this:

enter image description here So, the lines of my string marked with red arrows I want see entirely in the second column, like in the picture №1.


Solution

  • The idea is to split the text into blocks and single lines and to use for each part

    - (void)drawInRect:(CGRect)rect;
    

    or

    void CTLineDraw(CTLineRef line, CGContextRef context);
    

    Solution:

    @import CoreText;
    
    <...>
    
    - (IBAction)createPDF:(id)sender {
        PDFFileName = <yourString>;
        PDFPath = <yourPath>;
        [self generatePdfWithFilePath:PDFPath];
    }
    
    - (void)generatePdfWithFilePath:(NSString *)thefilePath {
        UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil);
        BOOL done = NO;
        do {
            UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 712), nil);
            [self drawText];
            done = YES;
        }
        while (!done);
        UIGraphicsEndPDFContext();
    }
    
    - (void)drawText {
        CGContextRef currentContext = UIGraphicsGetCurrentContext();
    
        //Here you can set up attributes for your text
        NSDictionary *attributesForText = @{
                                            NSFontAttributeName:[UIFont fontWithName:@"Georgia" size:12]
                                            };
    
        //Drawing text in line
        NSMutableAttributedString *stringOneAttributed = [[NSMutableAttributedString alloc] initWithString:stringOne attributes:attributesForText];
        CTLineRef stringOneLine = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)(stringOneAttributed));
        CGContextSetTextPosition(currentContext, x, y);
        CTLineDraw(stringOneLine, currentContext);
        CFRelease(stringOneLine);
    
        //Drawing block of text in rectangle
        NSMutableAttributedString *stringTwoAttributed = [[NSMutableAttributedString alloc] initWithString:stringTwo attributes:attributesForText];
        [stringTwoAttributed drawInRect:CGRectMake(x, y, width, height)];
    }