代码之家  ›  专栏  ›  技术社区  ›  netdigger

当包含特定字符时,UILabel文本在PDF中重复

  •  1
  • netdigger  · 技术社区  · 6 年前

    我正在生成一个类似以下内容的PDF文件:

    1. UIGraphicsBeginPDFContextToFile
    2. layer.render(in: context)
    3. UIGraphicsEndPDFContext

    昨天,我找到了一个修复方法,使所有文本向量都基于这个答案(基本上就是这个答案) https://stackoverflow.com/a/9056861/897465 ).

    这真的很好,文本是向量和可搜索的,等等。

    除了一件恼人的事。

    每次 UILabel 包含字符“”,文本在PDF中有点重复,如下图所示。可能还有其他角色也会导致这种情况。 enter image description here

    下面我举了一个小例子来说明这一点。如果你在模拟器中运行这个程序,你会在 /tmp/test.pdf 在那里你可以看到自己的问题。

    我想我应该提交一个rdar,但我真的希望有一些好的解决方法(好的意思是不检查 label.text 包含“Å”)。考虑到整个解决方案,我认为苹果不会解决这个问题( 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)
            }
        }
    
    }
    
    0 回复  |  直到 6 年前