【问题标题】:SwiftUI: Full screen View over NavigationBar and TabBarSwiftUI:NavigationBar 和 TabBar 的全屏视图
【发布时间】:2021-06-07 09:17:39
【问题描述】:

我正在尝试在 SwiftUI 中为我的应用添加全屏视图。这样做的目的是要有一个淡入的“阴影”,这将使屏幕变暗并将焦点集中在自定义弹出窗口上,从而禁用背景中的内容。请参阅下面的视觉示例:

我试图在其上添加此阴影的视图嵌入在一个复杂的 NavigationView 堆栈中(有几层深,通过 NavigationLink 访问),并且还有一个可见的 TabBar。到目前为止,我已经尝试将NavigationView 嵌入ZStack 并在顶部添加Rectangle() 但无济于事,NavigationBar 和TabBar 仍然位于此视图的顶部。我也尝试过使用 .zIndex() 修饰符,但这似乎什么也没做。

非常感谢任何帮助,

谢谢

【问题讨论】:

  • 您能否显示根视图的代码(可能会被简化) - 解决方案可能取决于它。

标签: swift swiftui fullscreen


【解决方案1】:

您不需要处理 zIndex,因为您覆盖了整个屏幕!即使您不需要禁用当前视图以使用 PopUp,因为 PopUp 再次位于顶层。 zIndex 在您没有覆盖屏幕时会有所帮助,这是一种方法:

struct ContentView: View {
    
    @State private var isPresented: Bool = Bool()
    
    var body: some View {
        
        NavigationView {
            
            VStack {
                
                Button("Show Custom PopUp View") { isPresented.toggle() }

            }
            .navigationTitle("Navigation Title")
            
        }
        .customPopupView(isPresented: $isPresented, popupView: { popupView })
        
    }
    
    var popupView: some View {
        
        RoundedRectangle(cornerRadius: 20.0)
            .fill(Color.white)
            .frame(width: 300.0, height: 200.0)
            .overlay(
                
                Image(systemName: "xmark").resizable().frame(width: 10.0, height: 10.0)
                    .foregroundColor(Color.black)
                    .padding(5.0)
                    .background(Color.red)
                    .clipShape(Circle())
                    .padding()
                    .onTapGesture { isPresented.toggle() }
                
                , alignment: .topLeading)
            
            .overlay(Text("Custom PopUp View!"))
            .transition(AnyTransition.scale)
            .shadow(radius: 10.0)
        
    }
}


struct CustomPopupView<Content, PopupView>: View where Content: View, PopupView: View {
    
    @Binding var isPresented: Bool
    @ViewBuilder let content: () -> Content
    @ViewBuilder let popupView: () -> PopupView
    let backgroundColor: Color
    let animation: Animation?
    
    var body: some View {
        
        content()
            .animation(nil, value: isPresented)
            .overlay(isPresented ? backgroundColor.ignoresSafeArea() : nil)
            .overlay(isPresented ? popupView() : nil)
            .animation(animation, value: isPresented)
        
    }
}

extension View {
    func customPopupView<PopupView>(isPresented: Binding<Bool>, popupView: @escaping () -> PopupView, backgroundColor: Color = .black.opacity(0.7), animation: Animation? = .default) -> some View where PopupView: View {
        return CustomPopupView(isPresented: isPresented, content: { self }, popupView: popupView, backgroundColor: backgroundColor, animation: animation)
    }
}

【讨论】:

    【解决方案2】:

    这就是我想要的方式。

    struct ContentView: View {
        
        @State var showingShade = false
        
        var body: some View {
    
            ZStack{
                
                //       Your other views goes here
                
                if showingShade{
                    Rectangle()
                        .ignoresSafeArea()
                        .foregroundColor(.black)
                        .opacity(0.5)
                }
            }
        }
    }
    

    然后当您希望阴影出现时,只需设置showingShade = true。使用与 PopUp 相同的 var 可能是个好主意。

    要禁用视图,您可以在要禁用的特定视图上使用 .disabled() 修饰符。

    【讨论】:

      猜你喜欢
      • 2021-11-19
      • 2010-11-21
      • 2016-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多