I am currently creating PDF documents from a UIView in iOS by using CALayer and the renderInContext method.
The problem I am facing is the sharpness of labels. I have created a UILabel subclass that overrides drawLayer like so:
/** Overriding this CALayer delegate method is the magic that allows us to draw a vector version of the label into the layer instead of the default unscalable ugly bitmap */
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
BOOL isPDF = !CGRectIsEmpty(UIGraphicsGetPDFContextBounds());
if (!layer.shouldRasterize && isPDF)
[self drawRect:self.bounds]; // draw unrasterized
else
[super drawLayer:layer inContext:ctx];
}
This method lets me draw nice crisp text, however, the problem is with other views that I don’t have control over. Is there any method that would allow me to do something similar for labels embedded in UITableView or UIButton. I guess I’m looking for a way to iterate through the view stack and do something to let me draw sharper text.
Here is an example:
This text renders nicely (my custom UILabel subclass)

The text in a standard segmented control isn’t as sharp:

Edit: I am getting the context to draw into my PDF as follows:
UIGraphicsBeginPDFContextToData(self.pdfData, CGRectZero, nil);
pdfContext = UIGraphicsGetCurrentContext();
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);
[view.layer renderInContext:pdfContext];
I ended up traversing the view hierarchy and setting every
UILabelto my custom subclass that overridesdrawLayer.Here is how I traverse the views:
And how I change the class:
The comparison:
Old:
New:
Not sure if there is a better way to do this, but it seems to work for my purposes.
EDIT: Found a more generic way to do this that doesn’t involve changing the class or traversing through the whole view hierarchy. I am using method swizzling. This method also lets you do cool things like surrounding every view with a border if you want. First I created a category
UIView+PDFwith my custom implementation of thedrawLayermethod, then in theloadmethod I use the following:Worked from the example here: http://darkdust.net/writings/objective-c/method-swizzling