SwiftUI:通过NavigationBar和TabBar全屏查看

biswetbf  于 2023-06-21  发布在  Swift
关注(0)|答案(3)|浏览(135)

我正在尝试在SwiftUI中添加全屏视图。这样做的目的是为了有一个“阴影”,这将使屏幕变暗,并将焦点带到一个自定义的弹出窗口,禁用背景中的内容。下面是一个可视化示例:

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

7eumitmz

7eumitmz1#

你不需要在zIndex上工作,因为你覆盖了所有屏幕!即使你不需要禁用您的当前视图使用弹出窗口的工作,因为再次弹出窗口已经在顶层。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)
    }
}

gdx19jrr

gdx19jrr2#

这就是我的想法。

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()修饰符。

8nuwlpux

8nuwlpux3#

对SwiftUI来说相当陌生,但我能够使用视图修饰符实现上述解决方案

struct CustomPopUpViewModifier<PopupView: View>: ViewModifier {

    let popupView: PopupView
    let backgroundColor: Color
    let animation: Animation?

    @Binding var isPresented: Bool

    func body(content: Content) -> some View {
        content
            .animation(nil, value: isPresented)
            .overlay(isPresented ? backgroundColor.ignoresSafeArea() : nil)
            .overlay(isPresented ? popupView : nil)
            .animation(animation, value: isPresented)
    }
}

并像这样使用它:

yourView
        .modifier(CustomPopUpViewModifier(popupView: InfoView(isPresented: $showingInfoModal,
                                                              viewModel: viewModel),
                                          backgroundColor: .black.opacity(0.5),
                                          animation: .default,
                                          isPresented: $showingInfoModal))

似乎为我掩盖了导航栏/项目

相关问题