Могут ли NSLayoutConstraints отображаться с десятичными константами? - PullRequest
1 голос
/ 09 апреля 2019

Я создал несколько UIViews внутри UIScrollView, которые изменяют размер динамически на основе значений, которые я печатаю в текстовые поля высоты и ширины. Как только размер UIView изменится, я сохраню содержимое UIScrollView в виде данных PDF.

Я считаю, что размеры UIView в 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 Ответ

1 голос
/ 09 апреля 2019

Вы не должны использовать layer.render (in :) для рендеринга вашего pdf. Причина всегда третья, потому что вы должны быть на 3х устройстве (это будет 1/2 на 2х устройстве и просто 1 на 1х устройстве), поэтому на точку приходится 3 пикселя. Когда iOS преобразует ваши ограничения в пиксели, лучше всего округлить до ближайшей трети, потому что она выбирает целочисленный пиксель. PDF-файл может иметь гораздо более высокую плотность пикселей (или использовать векторную графику с бесконечным) разрешением, поэтому вместо использования layer.render (in :), который сбрасывает пиксели в растеризованном векторном слое в ваш PDF-файл, вы должны фактически нарисовать содержимое в контекст PDF вручную (т. е. используйте кривую UIBezier, UIImage.draw и т. д.). Это позволит PDF-файлу записывать полное разрешение любых ваших растровых изображений и позволит фиксировать любые используемые вами векторы без разложения их на растеризованные пиксели, которые ограничены экраном устройства, на котором вы находитесь.

...