Я создаю PDF что-то вроде:
UIGraphicsBeginPDFContextToFile
layer.render(in: context)
UIGraphicsEndPDFContext
Вчера я нашел исправление, чтобы сделать весь текст векторным (в основном этот ответ https://stackoverflow.com/a/9056861/897465).
Это сработало очень хорошо, текст векторов и доступен для поиска и т. Д.
За исключениемза одну раздражающую вещь.
Каждый раз, когда UILabel
содержит символ «Å», текст вроде дублируется в PDF, как на рисунке ниже. Возможно, есть и другие символывызвать это.
У меня есть небольшой пример, который демонстрирует это ниже. Если вы запустите это в симуляторе, вы получите PDF в /tmp/test.pdf
, где вы можетепосмотрите на проблему самостоятельно.
Полагаю, мне следует подать rdar, но мне бы очень хотелось найти хороший обходной путь (хороший смысл - не проверять, содержит ли label.text
"Å"). Так как я не думаю, что эточто-то, что Apple исправит, учитывая весь обходной путь для начала (PDFLabel
).
import UIKit
class PDFLabel: UILabel {
override func draw(_ layer: CALayer, in ctx: CGContext) {
let isPDF = !UIGraphicsGetPDFContextBounds().isEmpty
if !layer.shouldRasterize && isPDF {
draw(bounds)
} else {
super.draw(layer, in: ctx)
}
}
}
func generatePDFWith(_ texts: [String]) {
let paper = CGRect(origin: .zero, size: CGSize(width: 876, height: 1239))
UIGraphicsBeginPDFContextToFile("/tmp/test.pdf", paper, [
kCGPDFContextCreator as String: "SampleApp"
])
texts.forEach { text in
UIGraphicsBeginPDFPage()
let v = UIView()
let label = PDFLabel()
label.text = text
label.textColor = .black
v.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
v.addSubview(label)
v.widthAnchor.constraint(equalToConstant: 500).isActive = true
v.heightAnchor.constraint(equalToConstant: 500).isActive = true
label.centerXAnchor.constraint(equalTo: v.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: v.centerYAnchor).isActive = true
v.setNeedsLayout()
v.layoutIfNeeded()
v.layer.render(in: UIGraphicsGetCurrentContext()!)
}
UIGraphicsEndPDFContext();
print("Done!")
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
generatePDFWith([
"Ångavallen",
"Hey Whatsapp?",
"Änglavallen",
"Örebro",
"Råå",
"RÅÅ",
"Å",
"Ål",
])
}
}
РЕДАКТИРОВАТЬ : Небольшой прогресс в отладке, кажется, что функция draw
вызывается два раза, и в первый раз она немного «выключается», если у нее есть «Å» (возможно, любой символ больше, чем прямоугольник).
Так что это исправило для меня (как бы ужасно это ни было):
class PDFLabel: UILabel {
var count = 0
override func draw(_ layer: CALayer, in ctx: CGContext) {
let isPDF = !UIGraphicsGetPDFContextBounds().isEmpty
if isPDF {
if count > 0 { draw(bounds) }
count += 1
} else if !layer.shouldRasterize {
draw(bounds)
} else {
super.draw(layer, in: ctx)
}
}
}