Printing Support

We’ve just recently added printing support to Hum. If you tap the share button you’ll see a print button next to the email and messages. To my surprise, it was actually quite easy.

Here is what our print method ended up looking like.

UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];
    
UIPrintPageRenderer *renderer = [[UIPrintPageRenderer alloc] init];
renderer.headerHeight = 40.0f; //Optically add padding to the top of the page.
renderer.footerHeight = 30.0f; //Add some padding on the footer as well.
controller.printPageRenderer = renderer;
    
UISimpleTextPrintFormatter *formatter = [[UISimpleTextPrintFormatter alloc] initWithText:self.song.lyrics];
    
controller.printFormatter = formatter;
formatter.font = [UIFont fontWithName:@"Whitney-Print" size:14.0f]; //Change the typeface and size of our text.
formatter.contentInsets = UIEdgeInsetsMake(0.0f, 30.0f, 0.0f, 30.0f); //Add some spacing on the left and right.
    
[renderer addPrintFormatter: formatter startingAtPageAtIndex: 0];
    
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.jobName = self.song.nameOrPlaceholder;
printInfo.outputType = UIPrintInfoOutputGrayscale;
controller.printInfo = printInfo;
    
controller.showsNumberOfCopies = YES; //Printing lyrics is usually for sharing in a rehearsal setting.
    
[controller presentAnimated:YES completionHandler:NULL];

That’s it.

But, as I’ve experienced with every simple feature in Cocoa, there’s always at least one ‘gotcha’. Here’s what I ran into:

1. Using custom fonts is easy, so long as you aren’t using an .otf. When using an .otf, it would print fine in the simulator, but as soon as there was any real printer output, iOS would fall back to the nearest typeface that worked. When I swapped an .otf for .ttf of our typeface, it worked just fine in both the simulator and real-life printing. I didn’t find this distinction in any of my googling.

2. Default page margins are way too close to the edge of the printed page. I thought that setting some contentInsets would handle it just fine, but no. By design, the print formatter doesn’t allow for a bottom inset. With a top inset it works great on the first page, but subsequent pages it’s ignored. I had to go with a mixed approach and build a renderer to add empty headers and footers for vertical padding, and insets for left and right spacing.

3. If you want leading / line-spacing that isn’t incredibly tight, you’ll need a workaround. I chose to open up our typeface and manually adjust its vertical metrics so I could fine-tune how spread apart those lines were. I exported a TTF with a custom name and metrics so I wouldn’t get them confused in our UI declarations. After some tweaking I found these lyrics to be much more legible than the defaults. I wasn’t able to find a way to change the leading in code alone.

Standard / Customized

Standard / Customized