#ios #swift #uiview #pdf-generation #nslayoutconstraint
#iOS #swift #uiview #генерация pdf #nslayoutconstraint
Вопрос:
Я создал несколько пользовательских представлений внутри UIScrollView, которые изменяют размер динамически на основе значений, которые я ввожу в текстовые поля Height и Width. После изменения размера UIView я сохраняю содержимое UIScrollView в виде данных PDF.
Я обнаружил, что размеры пользовательского интерфейса в формате PDF (при измерении в 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)
}
}
Ответ №1:
Вы не должны использовать layer.render (в:) для отображения вашего pdf. Причина, по которой он всегда является третьим, заключается в том, что вы должны быть на устройстве 3x (это было бы 1/2 на устройстве 2x и просто 1 на устройстве 1x), поэтому на точку приходится по 3 пикселя. Когда iOS преобразует ваши ограничения в пиксели, лучшее, что он может сделать, это округлить до ближайшей трети, потому что он выбирает целочисленный пиксель. PDF-файл может иметь гораздо более высокую плотность пикселей (или использовать векторное изображение с бесконечным разрешением), поэтому вместо использования layer.render (в:), который загружает пиксели из растрированного векторного слоя в ваш PDF-файл, вам следует на самом деле отрисовать содержимое в контексте PDF вручную (т. Е. Использовать UIBezier curve, UIImage.draw и т.д.). Это позволит pdf сохранять полное разрешение любых имеющихся у вас растрированных изображений и позволит ему захватывать любые используемые вами векторы, не превращая их в растрированные пиксели, которые ограничены экраном устройства, на котором вы находитесь.