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

Posted

技术标签:

【中文标题】如何阻止 drawHierarchy 使我的应用闪烁/闪烁?【英文标题】:How do I stop drawHierarchy from making my app flicker/flash? 【发布时间】:2021-07-20 15:19:08 【问题描述】:

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

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

但是,一旦我实际运行它,它会导致我的应用程序中的某些元素在每次 drawHierarchy 运行时闪烁。

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

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

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

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

【问题讨论】:

你能分享你的项目吗?它没有出现在我的 @Niv 这是我所看到的基本复制:github.com/connorlr/drawHierarchy-test 如果您单击“捕获”按钮,它会导致密码字段中的任何输入闪烁 哈哈,现在我明白了...它在闪​​烁,因为它是一个密码,Apple 故意设置了它,这样分享会更安全... 它也会使键盘覆盖层闪烁,即使键盘覆盖层不在我正在渲染的视图层次结构中。同样,即使我将根视图设置为隐藏,它仍然会闪烁,即使它不会绘制密码字段。 【参考方案1】:

编辑

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

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)
            )
        
    

第一次尝试:

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

使用的代码:

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)
            )
        
    

【讨论】:

我已经更新了我的示例来演示我的问题。即使我没有捕获键盘或密码字段,它们仍然会不一致地闪烁。 感谢您的更新。它看起来确实像 view.layer.render(in: context.cgContext) 渲染时没有闪烁,但不幸的是,结果在输入上的圆角矩形裁剪存在一些视觉问题

以上是关于如何阻止 drawHierarchy 使我的应用闪烁/闪烁?的主要内容,如果未能解决你的问题,请参考以下文章

阻止公共访问设置的哪些组合使我的 s3 存储桶对所有人可见?

如何使我的 Android 应用符合“后台位置政策”

被拒绝后,如何使我的应用在应用商店“可批准”?

如何使我的应用程序对所有设备可见?

怎么用xposed阻止QQ删除闪照阿

如何通过覆盖 BackButton 使我的 PhoneGap android 应用程序 onPause?