I've have a class that snapshots the contents of a scroll view by changing the contentOffset of the scroll view and translating the current transformation matrix, as it creates new pages in a PDF context. The result is a PDF that contains all of the contents of the scroll view, in PDF-page-sized chunks.
On iPad, this works in both orientations and both directions, but on iPhone, the snapshot fails (an empty PDF is generated) when the device is in landscape orientation. I was wondering if this has to do with the way iOS handles rotation on iPhone.
Is there something that I'm missing, or doing incorrectly?
Here's my code:
class ScrollViewSnapshotter: NSObject {
func PDFWithScrollView(scrollview: UIScrollView) -> NSData {
let pageDimensions = scrollview.bounds
let pageSize = pageDimensions.size
let totalSize = scrollview.contentSize
let numberOfPagesThatFitHorizontally = Int(ceil(totalSize.width / pageSize.width))
let numberOfPagesThatFitVertically = Int(ceil(totalSize.height / pageSize.height))
let outputData = NSMutableData()
UIGraphicsBeginPDFContextToData(outputData, pageDimensions, nil)
let savedContentOffset = scrollview.contentOffset
let savedContentInset = scrollview.contentInset
scrollview.contentInset = UIEdgeInsetsZero
if let context = UIGraphicsGetCurrentContext()
{
for indexHorizontal in 0 ..< numberOfPagesThatFitHorizontally
{
for indexVertical in 0 ..< numberOfPagesThatFitVertically
{
UIGraphicsBeginPDFPage()
let offsetHorizontal = CGFloat(indexHorizontal) * pageSize.width
let offsetVertical = CGFloat(indexVertical) * pageSize.height
scrollview.contentOffset = CGPointMake(offsetHorizontal, offsetVertical)
CGContextTranslateCTM(context, -offsetHorizontal, -offsetVertical) // NOTE: Negative offsets
scrollview.layer.renderInContext(context)
}
}
}
UIGraphicsEndPDFContext()
scrollview.contentInset = savedContentInset
scrollview.contentOffset = savedContentOffset
return outputData
}
}
I'm wondering if iPad doesn't do the same transforms on the current transformation matrix that the iPhone does. Is this true?
You should use CGAffineTransform. The affine transform functions operate on and return a CGAffineTransform data structure. The affine transform functions for Quartz operate on matrices, not on CTMs. You should use these ones to construct a matrix itself you then apply it to the CTM by calling a concatenation function CGContextConcatCTM.
Look at Interface Orientation article. There are some useful tips on transformation matrix.
Or you can use an extension:
extension CGAffineTransform {
public func translatedBy(x tx: CGFloat, y ty: CGFloat) -> CGAffineTransform
public func rotate(by angle: CGFloat) -> CGAffineTransform
public func scaledBy(x sx: CGFloat, y sy: CGFloat) -> CGAffineTransform
}

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With