如何阻止 drawHierarchy 使我的应用程序闪烁/闪烁?

时间:2021-07-20 15:19:08

标签: ios swift uikit uigraphicscontext uigraphicsrenderer

我正在尝试使用 UIGraphicsPDFRenderer 将我的应用程序的主视图转换为 PDF 数据。代码看起来像这样:

let pdfRenderer = UIGraphicsPDFRenderer()
let pdfData = pdfRenderer.pdfData { context in
  context.beginPage()
  view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}

但是,一旦我真正运行它,它会导致我的应用程序中的某些元素在每次 drawHierarchy 运行时闪烁。 this is what it looks like when run every second

我可以将 afterScreenUpdates 更改为 false 以防止发生这种情况,但我需要视图的最新更新才能使我的捕获准确无误(我隐藏了一个子视图不被捕获)

我也尝试过使用 view.layer.render(in: context),但捕获的结果不准确(缺少背景颜色)。

有没有办法避免闪烁?我不想捕获密码字段或键盘,但我绝对不希望它们闪烁。

Here 是闪烁行为的非常基本的再现。如果您在密码字段中输入并单击“捕获”,密码字段的输入将闪烁。

1 个答案:

答案 0 :(得分:0)

编辑

试图以这种方式捕获它,它甚至捕获了密码字段。

enter image description here

class Capture {
    static func capture() {
        
        let directory = FileManager.default.urls(for: FileManager.SearchPathDirectory.cachesDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first!
        let filePath =  directory.appendingPathComponent("Test.pdf")
        print(filePath)
        
        if let rootView = UIApplication.shared.windows.first?.rootViewController?.view {
            let pdfRenderer = UIGraphicsPDFRenderer(bounds: rootView.bounds)
            try! pdfRenderer.writePDF(to: filePath, withActions: { (context) in
                context.beginPage(withBounds: rootView.bounds, pageInfo: [:])
                rootView.layer.render(in: context.cgContext)
            })
        }
    }
}

第一次尝试:

它会闪烁,因为它在捕获屏幕时隐藏了密码和关键字:

enter image description here

使用的代码:

class Capture {
    static func capture() {
        
        let directory = FileManager.default.urls(for: FileManager.SearchPathDirectory.cachesDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first!
        let filePath =  directory.appendingPathComponent("Test.pdf")
        print(filePath)
        
        if let rootView = UIApplication.shared.windows.first?.rootViewController?.view {
            let pdfRenderer = UIGraphicsPDFRenderer(bounds: rootView.bounds)
            try! pdfRenderer.writePDF(to: filePath, withActions: { (context) in
                context.beginPage(withBounds: rootView.bounds, pageInfo: [:])
                rootView.drawHierarchy(in: rootView.bounds, afterScreenUpdates: true)
            })
        }
    }
}