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

SwiftUI.sheet导致背景白色闪烁

  •  0
  • Tom  · 技术社区  · 3 月前

    我遇到了一个奇怪的问题,当显示/取消工作表时,我的背景视图的边缘会闪烁白色。这个问题似乎只有在系统处于亮模式时才可见,暗模式很好。

    你可以在这里看到- flickering video demo

    有人看到这个并知道如何修复它吗?

    import SwiftUI
    
    struct ContentView: View {
        
        @State private var isShowing: Bool = false
        
        var body: some View {
                ZStack {
                    Color.black
                        .ignoresSafeArea()
                    Button {
                        isShowing = true
                    } label: {
                        Label("show", systemImage: "questionmark.circle")
                    }
                }
                .sheet(isPresented: $isShowing) {
                    EmptyView()
            }
    
        }
    }
    
    2 回复  |  直到 3 月前
        1
  •  1
  •   Sweeper    3 月前

    通过检查视图层次结构,我们可以看到SwiftUI使用 UIHostingController The view 此主机控制器的 backgroundColor 设置为 UIColor.systemBackground .你的 Color.black 然后覆盖在上面。

    如您所知,当显示一张大的图纸时,图纸后面的视图会收缩并向下移动一点。当您拖动图纸时,纸张后面的视图也会移动一点点。这里发生的事情似乎是 颜色黑色 与不太同步 UIView 这就是它的宿主。因此,有时其中一些 .systemBackground 颜色下 颜色黑色 被揭露。 .system背景 在亮模式下是白色,所以你可以清楚地看到它。在暗模式下是黑色,所以它与 颜色黑色 而你却没有注意到。

    我认为你无法解决运动不同步的问题。你必须等待苹果来做这件事。你能做的就是将背景颜色设置为 UIColor.black 因此即使在光模式下也不明显。

    struct BackgroundFixer: UIViewControllerRepresentable {
        class VC: UIViewController {
            override func willMove(toParent parent: UIViewController?) {
                // "parent" will be the UIHostingController we want when this
                // is added as a background to the root ZStack
                parent?.view.backgroundColor = .black
            }
        }
        
        func makeUIViewController(context: Context) -> VC {
            VC()
        }
        
        func updateUIViewController(_ uiViewController: VC, context: Context) {
            
        }
    }
    
    // Add this to the ZStack
    
    ZStack {
        Color.black
            .ignoresSafeArea()
        Button {
            isShowing = true
        } label: {
            Label("show", systemImage: "questionmark.circle")
        }
    }
    .background {
        BackgroundFixer()
    }
    .sheet(isPresented: $isShowing) {
        EmptyView()
    }
    
        2
  •  0
  •   Benzy Neez    3 月前

    我发现这个问题很难在iOS 18.2的iPhone 16模拟器上重现,但当你上下滑动页面时,这个问题就很明显了。

    一个简单的解决方法是在 ZStack 并对其进行负填充,使其延伸到屏幕边缘之外。负填充不需要很大:

    ZStack {
        // ...
    }
    .background {
        Color.black
            .padding(-10)
            .ignoresSafeArea()
    }
    .sheet(isPresented: $isShowing) {
        // ...
    }