NSLayoutConstraints 可以用十进制常量渲染吗?
Can NSLayoutConstraints be rendered with decimal constants?
我在 UIScrollView 中创建了几个 UIView,它们会根据我在“高度”和“宽度”文本字段中键入的值动态调整大小。一旦 UIView 调整大小,我将 UIScrollView 的内容保存为 PDF 数据。
我发现 PDF 中 UIView 的尺寸(在 Adobe Illustrator 中测量时)总是四舍五入到三分之一。
例如:
1.5 -> 1.333
1.75 -> 1.666
每次更新约束之前我都会检查常量值,它们是准确的。谁能解释为什么 UIViews 在呈现为 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)
}
}
您不应使用 layer.render(in:) 来呈现您的 pdf。它总是三分之一的原因是因为你必须在 3x 设备上(在 2x 设备上是 1/2,在 1x 设备上只是 1),所以每个点有 3 个像素。当 iOS 将您的约束转换为像素时,它能做的最好的事情就是四舍五入到最接近的三分之一,因为它选择了一个整数像素。 pdf 可以具有更高的像素密度(或使用无限矢量艺术)分辨率,因此不要使用 layer.render(in:),这是将光栅化矢量图层中的像素转储到 PDF 中,您应该实际绘制手动将内容导入 PDF 上下文(即使用 UIBezier 曲线、UIImage.draw 等)。这将允许 pdf 捕获您拥有的任何光栅化图像的完整分辨率,并允许它捕获您使用的任何矢量,而不会将它们降级为受您碰巧所在的设备屏幕限制的光栅化像素。
我在 UIScrollView 中创建了几个 UIView,它们会根据我在“高度”和“宽度”文本字段中键入的值动态调整大小。一旦 UIView 调整大小,我将 UIScrollView 的内容保存为 PDF 数据。
我发现 PDF 中 UIView 的尺寸(在 Adobe Illustrator 中测量时)总是四舍五入到三分之一。
例如:
1.5 -> 1.333
1.75 -> 1.666
每次更新约束之前我都会检查常量值,它们是准确的。谁能解释为什么 UIViews 在呈现为 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)
}
}
您不应使用 layer.render(in:) 来呈现您的 pdf。它总是三分之一的原因是因为你必须在 3x 设备上(在 2x 设备上是 1/2,在 1x 设备上只是 1),所以每个点有 3 个像素。当 iOS 将您的约束转换为像素时,它能做的最好的事情就是四舍五入到最接近的三分之一,因为它选择了一个整数像素。 pdf 可以具有更高的像素密度(或使用无限矢量艺术)分辨率,因此不要使用 layer.render(in:),这是将光栅化矢量图层中的像素转储到 PDF 中,您应该实际绘制手动将内容导入 PDF 上下文(即使用 UIBezier 曲线、UIImage.draw 等)。这将允许 pdf 捕获您拥有的任何光栅化图像的完整分辨率,并允许它捕获您使用的任何矢量,而不会将它们降级为受您碰巧所在的设备屏幕限制的光栅化像素。