SwiftUI:通过 NavigationBar 和 TabBar 的全屏视图
SwiftUI: Full screen View over NavigationBar and TabBar
我正在尝试在 SwiftUI 中为我的应用程序添加全屏视图。这样做的目的是要有一个淡入淡出的“阴影”,这将使屏幕变暗并将焦点带到自定义弹出窗口,从而禁用背景中的内容。请参阅下面的视觉示例:
我尝试添加此阴影的视图嵌入在一个复杂的 NavigationView 堆栈中(多层深,通过 NavigationLink
访问)并且还有一个可见的 TabBar。到目前为止,我已经尝试将 NavigationView
嵌入 ZStack
并在顶部添加 Rectangle()
但无济于事,NavigationBar 和 TabBar 仍然位于此视图的顶部。我也尝试过使用 .zIndex()
修饰符,但这似乎什么也没做。
非常感谢任何帮助,
谢谢
你不需要在 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)
}
}
这就是我想要的。
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 相同的变量可能是个好主意。
要禁用视图,您可以在要禁用的特定视图上使用 .disabled()
修饰符。
我正在尝试在 SwiftUI 中为我的应用程序添加全屏视图。这样做的目的是要有一个淡入淡出的“阴影”,这将使屏幕变暗并将焦点带到自定义弹出窗口,从而禁用背景中的内容。请参阅下面的视觉示例:
我尝试添加此阴影的视图嵌入在一个复杂的 NavigationView 堆栈中(多层深,通过 NavigationLink
访问)并且还有一个可见的 TabBar。到目前为止,我已经尝试将 NavigationView
嵌入 ZStack
并在顶部添加 Rectangle()
但无济于事,NavigationBar 和 TabBar 仍然位于此视图的顶部。我也尝试过使用 .zIndex()
修饰符,但这似乎什么也没做。
非常感谢任何帮助,
谢谢
你不需要在 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)
}
}
这就是我想要的。
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 相同的变量可能是个好主意。
要禁用视图,您可以在要禁用的特定视图上使用 .disabled()
修饰符。