SwiftUI 和 UIGraphicsImageRenderer 没有快照更新的视图

Posted

技术标签:

【中文标题】SwiftUI 和 UIGraphicsImageRenderer 没有快照更新的视图【英文标题】:SwiftUI and UIGraphicsImageRenderer not snapshotting updated View 【发布时间】:2021-10-08 03:19:39 【问题描述】:

我正在尝试对 SwiftUI 视图进行快照,但是当我更新该视图(例如文本)并对视图进行快照时,我返回的图像来自默认视图(视图的先前渲染,而不是更新的视图)

在这个代码示例中,有一个 TextView 要被快照,当点击它时它会更改/更新,然后按下按钮应该保存新更新的 View 并更改 TextView,但它会保存旧版本。

视图扩展为快照视图:

extension View 
    func snapshot() -> UIImage 
        let controller = UIHostingController(rootView: self)
        let view = controller.view
        
        let targetSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        view?.bounds = CGRect(origin: .zero, size: targetSize)
        view?.backgroundColor = .clear
        
        let renderer = UIGraphicsImageRenderer(size: targetSize)
        
        return renderer.image  _ in
            view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
        
    

ContentView 与按钮快照视图:

struct ContentView: View 
    var view: some View = ScreenShot()
    
    var body: some View 
        VStack 
            view
            
            Button("Save Image") 
                let image = view.snapshot()
                UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
            
        
    

要快照和更新的视图:

struct ScreenShot: View 
    @State var updateView = false
    
    var body: some View 
        Text("View to be snapshotted \(updateView ? "(Update)" : "")")
           .tapGesture 
               updateView.toggle()
           
    

这是初始视图:

这是更新后的视图:

这是被保存的视图:

【问题讨论】:

你能显示ScreenShot的代码吗? 您为“ContentView with button to snapshot View”和“View to be快照并更新”发布了完全相同的代码。 我的错,现在修复 这应该会有所帮助***.com/a/59333377/12299030 【参考方案1】:

发现从被快照的视图外部进行快照不会响应更新,尝试从“屏幕截图”视图内部调用快照函数并且它起作用了。

我相信这是正确的方法,但我也觉得可能有另一种方法(?)

【讨论】:

以上是关于SwiftUI 和 UIGraphicsImageRenderer 没有快照更新的视图的主要内容,如果未能解决你的问题,请参考以下文章

在SwiftUI项目中使用UIKit(SwiftUI和UIKit混合开发)

SwiftUI 和 UICloudSharingController 互相讨厌

iOS 14.0 之后如何解决 SwiftUI 中 RealmSwift.App 和 SwiftUI.App 的冲突?

SWIFTUI 和 Core Motion

SwiftUI - 用不同的动作响应点击和双击

UICollectionView 和 SwiftUI?