ios - 包含特定字符时,UILabel 文本在 PDF 中重复
问题描述
我正在生成一个类似的 PDF:
UIGraphicsBeginPDFContextToFile
layer.render(in: context)
UIGraphicsEndPDFContext
昨天,我找到了一个使所有文本基于向量的修复程序(基本上这个答案https://stackoverflow.com/a/9056861/897465)。
效果很好,文本是矢量和可搜索的,等等。
除了一件恼人的事情。
每次 aUILabel
包含字符“Å”时,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)
}
}
}
解决方案
推荐阅读
- shiny - Rstudio 服务器在部署 APP 时遇到问题
- android - 如果用户有双 sim 卡,则获取或设置选定的默认 sim 卡
- javascript - mouseup/down 整个 SPA 角度
- apache-kafka - Kafka 消费组清理
- kettle - 如何从 Pentaho 中的多个不同表创建 Fact 表
- keras - 如何在 Keras 中使用 h5 类型的预训练图像分类模型?
- c++ - Makefile 中的 $(objs): %.o : %.cpp 和 $(objs): $(objs:.o=.cpp) 有什么区别
- python - LDAP Auth:OU(组织单位)中的变量
- python-3.x - 当我需要使用两个堆栈组成队列时,如何检查队列是否为空?
- java - 检查多个哈希图是否为空