首页 > 解决方案 > NSLayoutConstraints 可以用十进制常量渲染吗?

问题描述

我在 UIScrollView 中创建了几个 UIView,它们根据我在 Height 和 Width 文本字段中键入的值动态调整大小。一旦 UIView 调整大小,我将 UIScrollView 的内容保存为 PDF 数据。

我发现 PDF 中 UIView 的尺寸(在 Adob​​e Illustrator 中测量时)总是四舍五入到三分之一。

例如:

1.5 -> 1.333

1.75 -> 1.666

我每次在更新约束之前检查常量值并且它们是准确的。任何人都可以解释为什么 UIView 在呈现为 PDF 后尺寸不正确?

@IBAction func updateDimensions(_ sender: Any) {

        guard let length = NumberFormatter().number(from:
            lengthTextField.text ?? "") else { return }

        guard let width = NumberFormatter().number(from:
            widthTextField.text ?? "") else { return }

        guard let height = NumberFormatter().number(from:
            heightTextField.text ?? "") else { return }

        let flapHeight = CGFloat(truncating: width)/2

        let lengthFloat = CGFloat(truncating: length)
        let widthFloat = CGFloat(truncating: width)
        let heightFloat = CGFloat(truncating: height)

        UIView.animate(withDuration: 0.3) {
            self.faceAWidthConstraint.constant = lengthFloat
            self.faceAHeightConstraint.constant = heightFloat
            self.faceBWidthConstraint.constant = widthFloat
            self.faceA1HeightConstraint.constant = flapHeight
            self.view.layoutIfNeeded()
        }
    }

    func createPDFfrom(aView: UIView, saveToDocumentsWithFileName fileName: String)
    {
        let pdfData = NSMutableData()
        UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil)
        UIGraphicsBeginPDFPage()

        guard let pdfContext = UIGraphicsGetCurrentContext() else { return }

        aView.layer.render(in: pdfContext)
        UIGraphicsEndPDFContext()

        if let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
            let documentsFileName = documentDirectories + "/" + fileName
            debugPrint(documentsFileName)
            pdfData.write(toFile: documentsFileName, atomically: true)
        }
    }

标签: iosswiftuiviewpdf-generationnslayoutconstraint

解决方案


您不应该使用 layer.render(in:) 来渲染您的 pdf。它总是三分之一的原因是因为您必须在 3x 设备上(在 2x 设备上是 1/2,在 1x 设备上只是 1),所以每个点有 3 个像素。当 iOS 将您的约束转换为像素时,它所能做的最好的事情就是四舍五入到最接近的三分之一,因为它选择了一个整数像素。pdf 可以具有更高的像素密度(或使用具有无限的矢量图)分辨率,因此不要使用 layer.render(in:) 将光栅化矢量图层中的像素转储到 PDF 中,您实际上应该将内容绘制到手动 PDF 上下文(即使用 UIBezier 曲线、UIImage.draw 等)。


推荐阅读