SwiftUI:从先前视图未涵盖的滑块菜单启动新视图
SwiftUI: Lauch new view from a slider menu that is not covered by previous view
我对 SwiftUI 完全陌生,所以我希望这不是一个愚蠢的问题。在我的项目中,我在右上角有一个主页视图(一张地图)和一个菜单按钮。单击该按钮后,我的菜单将从左侧滑入。对于每个菜单项,我想使用 NavigationLink 跳转到下一个详细视图。
现在问题来了: 当我点击菜单项(例如付款)时,我看到了视图,但我的按钮和地图仍然在该视图之上而且我无法摆脱它,或者至少我不知道如何.. :(。
我看到了一些类似的问题,但我无法让它适用于我的情况。
这是我在菜单视图为真时的视图
这是我的问题视图。当我点击例如。我无法摆脱该视图中的地图和按钮
这是我的 HomeView(地图和按钮)代码:
import SwiftUI
struct HomeView: View {
@State var showMenu = false
var body: some View {
let drag = DragGesture()
.onEnded {
if [=10=].translation.width < -100 {
withAnimation {
self.showMenu = false
}
}
}
return GeometryReader { geometry in
ZStack(alignment: .leading) {
if self.showMenu {
SlideInMenuView()
.frame(width: geometry.size.width/1)
.transition(.move(edge: .leading))
}
HomeSupportView()
.frame(width: geometry.size.width, height: geometry.size.height)
.cornerRadius(20)
.scaleEffect(self.showMenu ? 0.8 : 1)
.offset(x: self.showMenu ? 150 : 0, y : self.showMenu ? 50 : 0)
.disabled(self.showMenu ? true : false)
MenuButton(showMenu: self.$showMenu)
}
.gesture(drag)
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
struct MenuButton: View {
@Binding var showMenu: Bool
var body: some View {
Button(action: {
withAnimation {
self.showMenu.toggle()
}
}){
Image(systemName: "line.horizontal.3")
.imageScale(.large)
.frame(width: 100, height: 60)
.background(Color.black)
.clipShape(Circle())
.opacity(0.8)
.foregroundColor(.white)
.rotationEffect(.degrees(self.showMenu ? 90 : 0))
.scaleEffect(self.showMenu ? 1.2 : 1)
}
.padding(.top, -380)
}
}
这是我尝试使 NavigationLink 工作的菜单视图代码。我在 "Payments" HStack 上尝试了多个版本,但我无法让它工作
import SwiftUI
struct SlideInMenuView: View {
@State private var showingPaymentDetails = false
var body: some View {
NavigationView {
VStack(alignment: .leading) {
HStack {
Image(systemName: "person")
.foregroundColor(.gray)
.imageScale(.large)
Text("Profile")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 150.0)
HStack {
Image(systemName: "person.2.fill")
.foregroundColor(.gray)
.imageScale(.large)
Text("Matches")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
NavigationLink(destination:
PaymentDetailsView())
{
HStack {
Image(systemName: "creditcard")
.foregroundColor(.gray)
.imageScale(.large)
Text("Payments")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
}
HStack {
Image(systemName: "hammer")
.foregroundColor(.gray)
.imageScale(.large)
Text("Settings")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
Spacer()
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(red: 32/255, green: 32/255, blue: 32/255))
.edgesIgnoringSafeArea(.all)
}
}
}
struct SlideInMenuView_Previews: PreviewProvider {
static var previews: some View {
SlideInMenuView()
}
}
如果有人知道如何帮助我...
非常感谢你们。
保持健康。
干杯,
勒鲍勃
@Chris: This is how I want it to be. I put in 4 consecutive screenshots with the respective clicks.
SwiftUI 有一个 zIndex() 修饰符,您可以使用它来对视图进行排序。
这可能对您的情况有所帮助。
***** 更新的答案 *****
谢谢你的澄清图片
试试这个:
import SwiftUI
class Global : ObservableObject {
@Published var showMenu = true
@Published var showMenuButton = true
}
struct PaymentDetailsView : View {
@EnvironmentObject var global : Global
var body: some View {
Text("payment")
.onAppear() {
withAnimation() {
self.global.showMenuButton = false
}
}
.onDisappear() {
withAnimation() {
self.global.showMenuButton = true
}
}
}
}
struct HomeSupportView : View {
@EnvironmentObject var global : Global
var body: some View {
ZStack {
Rectangle().fill(Color.blue)
Text("home")
}
}
}
struct SlideInMenuView: View {
@EnvironmentObject var global : Global
@State private var showingPaymentDetails = false
var body: some View {
NavigationView {
VStack(alignment: .leading) {
HStack {
Image(systemName: "person")
.foregroundColor(.gray)
.imageScale(.large)
Text("Profile")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 150.0)
HStack {
Image(systemName: "person.2.fill")
.foregroundColor(.gray)
.imageScale(.large)
Text("Matches")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
NavigationLink(destination:
PaymentDetailsView().environmentObject(self.global))
{
HStack {
Image(systemName: "creditcard")
.foregroundColor(.gray)
.imageScale(.large)
Text("Payments")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
}
HStack {
Image(systemName: "hammer")
.foregroundColor(.gray)
.imageScale(.large)
Text("Settings")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
Spacer()
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(red: 32/255, green: 32/255, blue: 32/255))
.edgesIgnoringSafeArea(.all)
}
}
}
struct SlideInMenuView_Previews: PreviewProvider {
static var previews: some View {
SlideInMenuView().environmentObject(Global())
}
}
struct ContentView: View {
@EnvironmentObject var global : Global
var body: some View {
let drag = DragGesture()
.onEnded {
if [=10=].translation.width < -100 {
withAnimation {
self.global.showMenu = false
}
}
}
return GeometryReader { geometry in
ZStack(alignment: .leading) {
if self.global.showMenu {
SlideInMenuView()
.environmentObject(self.global)
.frame(width: geometry.size.width/1)
.transition(.move(edge: .leading))
.zIndex(3)
}
HomeSupportView()
.environmentObject(self.global)
.frame(width: geometry.size.width, height: geometry.size.height)
.cornerRadius(20)
.scaleEffect(self.global.showMenu ? 0.8 : 1)
.offset(x: self.global.showMenu ? 150 : 0, y : self.global.showMenu ? 50 : 0)
.disabled(self.global.showMenu ? true : false)
.zIndex((2))
MenuButton().environmentObject(self.global)
.zIndex(4)
}
.gesture(drag)
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(Global())
}
}
struct MenuButton: View {
@EnvironmentObject var global: Global
var body: some View {
Button(action: {
withAnimation {
self.global.showMenu.toggle()
}
}){
if self.global.showMenuButton {
Image(systemName: "line.horizontal.3")
.imageScale(.large)
.frame(width: 100, height: 60)
.background(Color.black)
.clipShape(Circle())
.opacity(0.8)
.foregroundColor(.white)
.rotationEffect(.degrees(self.global.showMenu ? 90 : 0))
.scaleEffect(self.global.showMenu ? 1.2 : 1)
} else {
EmptyView()
}
}
.padding(.top, -380)
}
}
我对 SwiftUI 完全陌生,所以我希望这不是一个愚蠢的问题。在我的项目中,我在右上角有一个主页视图(一张地图)和一个菜单按钮。单击该按钮后,我的菜单将从左侧滑入。对于每个菜单项,我想使用 NavigationLink 跳转到下一个详细视图。
现在问题来了: 当我点击菜单项(例如付款)时,我看到了视图,但我的按钮和地图仍然在该视图之上而且我无法摆脱它,或者至少我不知道如何.. :(。 我看到了一些类似的问题,但我无法让它适用于我的情况。
这是我在菜单视图为真时的视图
这是我的问题视图。当我点击例如。我无法摆脱该视图中的地图和按钮
这是我的 HomeView(地图和按钮)代码:
import SwiftUI
struct HomeView: View {
@State var showMenu = false
var body: some View {
let drag = DragGesture()
.onEnded {
if [=10=].translation.width < -100 {
withAnimation {
self.showMenu = false
}
}
}
return GeometryReader { geometry in
ZStack(alignment: .leading) {
if self.showMenu {
SlideInMenuView()
.frame(width: geometry.size.width/1)
.transition(.move(edge: .leading))
}
HomeSupportView()
.frame(width: geometry.size.width, height: geometry.size.height)
.cornerRadius(20)
.scaleEffect(self.showMenu ? 0.8 : 1)
.offset(x: self.showMenu ? 150 : 0, y : self.showMenu ? 50 : 0)
.disabled(self.showMenu ? true : false)
MenuButton(showMenu: self.$showMenu)
}
.gesture(drag)
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
struct MenuButton: View {
@Binding var showMenu: Bool
var body: some View {
Button(action: {
withAnimation {
self.showMenu.toggle()
}
}){
Image(systemName: "line.horizontal.3")
.imageScale(.large)
.frame(width: 100, height: 60)
.background(Color.black)
.clipShape(Circle())
.opacity(0.8)
.foregroundColor(.white)
.rotationEffect(.degrees(self.showMenu ? 90 : 0))
.scaleEffect(self.showMenu ? 1.2 : 1)
}
.padding(.top, -380)
}
}
这是我尝试使 NavigationLink 工作的菜单视图代码。我在 "Payments" HStack 上尝试了多个版本,但我无法让它工作
import SwiftUI
struct SlideInMenuView: View {
@State private var showingPaymentDetails = false
var body: some View {
NavigationView {
VStack(alignment: .leading) {
HStack {
Image(systemName: "person")
.foregroundColor(.gray)
.imageScale(.large)
Text("Profile")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 150.0)
HStack {
Image(systemName: "person.2.fill")
.foregroundColor(.gray)
.imageScale(.large)
Text("Matches")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
NavigationLink(destination:
PaymentDetailsView())
{
HStack {
Image(systemName: "creditcard")
.foregroundColor(.gray)
.imageScale(.large)
Text("Payments")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
}
HStack {
Image(systemName: "hammer")
.foregroundColor(.gray)
.imageScale(.large)
Text("Settings")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
Spacer()
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(red: 32/255, green: 32/255, blue: 32/255))
.edgesIgnoringSafeArea(.all)
}
}
}
struct SlideInMenuView_Previews: PreviewProvider {
static var previews: some View {
SlideInMenuView()
}
}
如果有人知道如何帮助我... 非常感谢你们。 保持健康。
干杯, 勒鲍勃
@Chris: This is how I want it to be. I put in 4 consecutive screenshots with the respective clicks.
SwiftUI 有一个 zIndex() 修饰符,您可以使用它来对视图进行排序。 这可能对您的情况有所帮助。
***** 更新的答案 *****
谢谢你的澄清图片
试试这个:
import SwiftUI
class Global : ObservableObject {
@Published var showMenu = true
@Published var showMenuButton = true
}
struct PaymentDetailsView : View {
@EnvironmentObject var global : Global
var body: some View {
Text("payment")
.onAppear() {
withAnimation() {
self.global.showMenuButton = false
}
}
.onDisappear() {
withAnimation() {
self.global.showMenuButton = true
}
}
}
}
struct HomeSupportView : View {
@EnvironmentObject var global : Global
var body: some View {
ZStack {
Rectangle().fill(Color.blue)
Text("home")
}
}
}
struct SlideInMenuView: View {
@EnvironmentObject var global : Global
@State private var showingPaymentDetails = false
var body: some View {
NavigationView {
VStack(alignment: .leading) {
HStack {
Image(systemName: "person")
.foregroundColor(.gray)
.imageScale(.large)
Text("Profile")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 150.0)
HStack {
Image(systemName: "person.2.fill")
.foregroundColor(.gray)
.imageScale(.large)
Text("Matches")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
NavigationLink(destination:
PaymentDetailsView().environmentObject(self.global))
{
HStack {
Image(systemName: "creditcard")
.foregroundColor(.gray)
.imageScale(.large)
Text("Payments")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
}
HStack {
Image(systemName: "hammer")
.foregroundColor(.gray)
.imageScale(.large)
Text("Settings")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
Spacer()
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(red: 32/255, green: 32/255, blue: 32/255))
.edgesIgnoringSafeArea(.all)
}
}
}
struct SlideInMenuView_Previews: PreviewProvider {
static var previews: some View {
SlideInMenuView().environmentObject(Global())
}
}
struct ContentView: View {
@EnvironmentObject var global : Global
var body: some View {
let drag = DragGesture()
.onEnded {
if [=10=].translation.width < -100 {
withAnimation {
self.global.showMenu = false
}
}
}
return GeometryReader { geometry in
ZStack(alignment: .leading) {
if self.global.showMenu {
SlideInMenuView()
.environmentObject(self.global)
.frame(width: geometry.size.width/1)
.transition(.move(edge: .leading))
.zIndex(3)
}
HomeSupportView()
.environmentObject(self.global)
.frame(width: geometry.size.width, height: geometry.size.height)
.cornerRadius(20)
.scaleEffect(self.global.showMenu ? 0.8 : 1)
.offset(x: self.global.showMenu ? 150 : 0, y : self.global.showMenu ? 50 : 0)
.disabled(self.global.showMenu ? true : false)
.zIndex((2))
MenuButton().environmentObject(self.global)
.zIndex(4)
}
.gesture(drag)
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(Global())
}
}
struct MenuButton: View {
@EnvironmentObject var global: Global
var body: some View {
Button(action: {
withAnimation {
self.global.showMenu.toggle()
}
}){
if self.global.showMenuButton {
Image(systemName: "line.horizontal.3")
.imageScale(.large)
.frame(width: 100, height: 60)
.background(Color.black)
.clipShape(Circle())
.opacity(0.8)
.foregroundColor(.white)
.rotationEffect(.degrees(self.global.showMenu ? 90 : 0))
.scaleEffect(self.global.showMenu ? 1.2 : 1)
} else {
EmptyView()
}
}
.padding(.top, -380)
}
}