Core Graphics'转换矩阵的工作方式与iPad不同?

时间:2016-04-25 16:50:52

标签: ios swift uiscrollview core-graphics

我已经a class通过更改滚动视图的contentOffset并翻译当前转换矩阵来快照滚动视图的内容,因为它在PDF上下文中创建了新页面。结果是一个PDF,其中包含滚动视图的所有内容,采用PDF页面大小的块。

在iPad上,这适用于两个方向和两个方向,但在iPhone上,当设备处于横向时,快照失败(生成空PDF)。我想知道这是否与iOS处理iPhone上的旋转方式有关。

我有什么遗失或做错了吗?

这是我的代码:

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
    }
}

我想知道iPad是否在iPhone当前的转换矩阵上进行相同的转换。这是真的吗?

3 个答案:

答案 0 :(得分:1)

您应该使用CGAffineTransform。仿射变换函数操作并返回CGAffineTransform数据结构。 Quartz的仿射变换函数在矩阵上运行,而不是CTMs。您应该使用这些构建矩阵本身,然后通过调用连接函数CTM将其应用于CGContextConcatCTM

查看Interface Orientation文章。关于转换矩阵有一些有用的提示。

或者您可以使用扩展程序:

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

答案 1 :(得分:0)

如果在拍摄PDF之前手动滚动,您也会在iPad上看到不正确的输出。

您必须考虑scrollView.bounds.offset:

CGContextTranslateCTM(
    context,
    -offsetHorizontal + pageDimensions.minX,
    -offsetVertical - pageDimensions.minY)

答案 2 :(得分:0)

我认为这应该为你做...只需在你的循环中添加一行:

    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

                // Translate again, with the original Content Offsets
                // Positive X, Negative Y
                CGContextTranslateCTM(context, savedContentOffset.x, -savedContentOffset.y)

                scrollview.layer.renderInContext(context)
            }
        }
    }