Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Core Graphics' transformation matrix work differently than iPad?

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?

like image 403
Moshe Avatar asked Dec 14 '25 03:12

Moshe


1 Answers

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
}

enter image description here

like image 109
Andy Jazz Avatar answered Dec 16 '25 17:12

Andy Jazz



Donate For Us

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