如何从 SwiftUI 中的侧边菜单导航到新视图
How to navigate from side menu in SwiftUI to new view
我正在开发具有带导航和侧面菜单的主页视图的应用程序。侧面菜单有 2 级菜单,即每个菜单条目都有子菜单。每当用户单击任何侧面子菜单时,应用程序都应显示新视图,但我无法实现此行为。我尝试了子菜单中的导航视图,但是子菜单被破坏了,我也尝试了 navigateTo,但它也没有用。
这是带有侧边菜单的主页视图 -
struct HomePageView: View {
@State var size = UIScreen.main.bounds.width / 1.6
var body: some View {
GeometryReader{ geometry in
NavigationView{
VStack{
ScrollView (.vertical, showsIndicators: true) {
anotherView()
HStack{
Spacer(minLength: 0)
}
}.frame(width: geometry.size.width)
}
.background(Image("background").resizable().scaledToFill().clipped())
.animation(.spring()).background(Color.lairBackgroundGray)
.navigationBarItems(leading: Button(action: {
self.size = 10
}, label: {
Image("menu")
.resizable()
.frame(width: 30, height: 30)
}).foregroundColor(.appHeadingColor), trailing:
Button(action: {
withAnimation {
print("profile is pressed")
}
}) {
HStack {
NavigationLink(destination: ProfileView()) {
LinearGradient.lairHorizontalDark
.frame(width: 30, height: 30)
.mask(
Image(systemName: "person.crop.circle")
.resizable()
.scaledToFit()
)
}
}
}
).navigationBarTitle("Home", displayMode: .inline)
.animation(.spring())
}.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
HStack{
menu(size: self.$size) // --> Side menu
.cornerRadius(20)
.padding(.leading, -self.size)
.offset(x: -self.size)
Spacer().background(Color.lairBackgroundGray)
}.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
.animation(.spring())
}
}
}
下面是侧边菜单视图,它是基于状态变量创建的-
struct menu : View {
@Binding var size : CGFloat
@State var logout: Bool = false
@State private var didSubMenuPressed: Bool = false
@State var sideMenuEntries = [
SideMenuData(index: 0, imageName: "info.circle",
menuText: "Info",
subMenu: ["Info1", "Info2", "Info3", "Info4"],
expand: false),
SideMenuData(index: 1, imageName: "doc.on.doc",
menuText: "Documents",
subMenu: ["Documents1", "Documents2"],
expand: false)
]
var body : some View{
VStack (alignment: .leading){
HStack{
Spacer()
Button(action: {
self.size = UIScreen.main.bounds.width / 1.6
}) {
Image("close").resizable()
.frame(width: 15, height: 15)
.padding()
}
.foregroundColor(.white)
.clipShape(Circle())
}
ForEach (sideMenuEntries.indices) { index in
VStack (alignment: .leading, spacing: 0, content: {
HStack{
Image(self.sideMenuEntries[index].imageName).resizable().frame(width: 25, height: 25)
.foregroundColor(.white)
Text(self.sideMenuEntries[index].menuText).fontWeight(.heavy).foregroundColor(.white)
if self.sideMenuEntries[index].subMenu.count > 1 {
Image(systemName: self.sideMenuEntries[index].expand ? "chevron.compact.up" : "chevron.compact.down")
.resizable()
.frame(width: 10, height: 10)
.foregroundColor(.white)
}
Image("logout-1").resizable().frame(width: 25, height: 25)//.padding(.leading, 5)
.foregroundColor(.white)
Text(self.sideMenuEntries[index].menuText).fontWeight(.heavy).foregroundColor(.white)
if self.logout {
//
}
}
.contentShape(Rectangle())
.onTapGesture {
self.sideMenuEntries[index].expand.toggle()
}
if self.sideMenuEntries[index].expand {
VStack (alignment: .leading){
ForEach (self.sideMenuEntries[index].subMenu.indices) { index1 in
Button(action: {
print("\(self.sideMenuEntries[index].subMenu[index1]) is pressed")
self.size = UIScreen.main.bounds.width / 1.6
self.didSubMenuPressed.toggle()
}){
Text(self.sideMenuEntries[index].subMenu[index1])
.foregroundColor(.white)
}
.padding([.top, .bottom], 7)
}
}
.padding(.top, 14)
.padding(.leading, 34)
}
})
}
Spacer()
}
.padding(.leading, 40)
.frame(width: UIScreen.main.bounds.width / 1.3)
.background(LinearGradient(
gradient: Gradient(
colors: [.buttonGradientStartColor, .buttonGradientEndColor]),
startPoint: .top,
endPoint: .bottom))
// if u want to change swipe menu background color
}
}
我找到了实现此行为的方法,在 HomePageview 中创建状态变量并在菜单中创建绑定变量,这解决了我的问题。
我正在开发具有带导航和侧面菜单的主页视图的应用程序。侧面菜单有 2 级菜单,即每个菜单条目都有子菜单。每当用户单击任何侧面子菜单时,应用程序都应显示新视图,但我无法实现此行为。我尝试了子菜单中的导航视图,但是子菜单被破坏了,我也尝试了 navigateTo,但它也没有用。
这是带有侧边菜单的主页视图 -
struct HomePageView: View {
@State var size = UIScreen.main.bounds.width / 1.6
var body: some View {
GeometryReader{ geometry in
NavigationView{
VStack{
ScrollView (.vertical, showsIndicators: true) {
anotherView()
HStack{
Spacer(minLength: 0)
}
}.frame(width: geometry.size.width)
}
.background(Image("background").resizable().scaledToFill().clipped())
.animation(.spring()).background(Color.lairBackgroundGray)
.navigationBarItems(leading: Button(action: {
self.size = 10
}, label: {
Image("menu")
.resizable()
.frame(width: 30, height: 30)
}).foregroundColor(.appHeadingColor), trailing:
Button(action: {
withAnimation {
print("profile is pressed")
}
}) {
HStack {
NavigationLink(destination: ProfileView()) {
LinearGradient.lairHorizontalDark
.frame(width: 30, height: 30)
.mask(
Image(systemName: "person.crop.circle")
.resizable()
.scaledToFit()
)
}
}
}
).navigationBarTitle("Home", displayMode: .inline)
.animation(.spring())
}.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
HStack{
menu(size: self.$size) // --> Side menu
.cornerRadius(20)
.padding(.leading, -self.size)
.offset(x: -self.size)
Spacer().background(Color.lairBackgroundGray)
}.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
.animation(.spring())
}
}
}
下面是侧边菜单视图,它是基于状态变量创建的-
struct menu : View {
@Binding var size : CGFloat
@State var logout: Bool = false
@State private var didSubMenuPressed: Bool = false
@State var sideMenuEntries = [
SideMenuData(index: 0, imageName: "info.circle",
menuText: "Info",
subMenu: ["Info1", "Info2", "Info3", "Info4"],
expand: false),
SideMenuData(index: 1, imageName: "doc.on.doc",
menuText: "Documents",
subMenu: ["Documents1", "Documents2"],
expand: false)
]
var body : some View{
VStack (alignment: .leading){
HStack{
Spacer()
Button(action: {
self.size = UIScreen.main.bounds.width / 1.6
}) {
Image("close").resizable()
.frame(width: 15, height: 15)
.padding()
}
.foregroundColor(.white)
.clipShape(Circle())
}
ForEach (sideMenuEntries.indices) { index in
VStack (alignment: .leading, spacing: 0, content: {
HStack{
Image(self.sideMenuEntries[index].imageName).resizable().frame(width: 25, height: 25)
.foregroundColor(.white)
Text(self.sideMenuEntries[index].menuText).fontWeight(.heavy).foregroundColor(.white)
if self.sideMenuEntries[index].subMenu.count > 1 {
Image(systemName: self.sideMenuEntries[index].expand ? "chevron.compact.up" : "chevron.compact.down")
.resizable()
.frame(width: 10, height: 10)
.foregroundColor(.white)
}
Image("logout-1").resizable().frame(width: 25, height: 25)//.padding(.leading, 5)
.foregroundColor(.white)
Text(self.sideMenuEntries[index].menuText).fontWeight(.heavy).foregroundColor(.white)
if self.logout {
//
}
}
.contentShape(Rectangle())
.onTapGesture {
self.sideMenuEntries[index].expand.toggle()
}
if self.sideMenuEntries[index].expand {
VStack (alignment: .leading){
ForEach (self.sideMenuEntries[index].subMenu.indices) { index1 in
Button(action: {
print("\(self.sideMenuEntries[index].subMenu[index1]) is pressed")
self.size = UIScreen.main.bounds.width / 1.6
self.didSubMenuPressed.toggle()
}){
Text(self.sideMenuEntries[index].subMenu[index1])
.foregroundColor(.white)
}
.padding([.top, .bottom], 7)
}
}
.padding(.top, 14)
.padding(.leading, 34)
}
})
}
Spacer()
}
.padding(.leading, 40)
.frame(width: UIScreen.main.bounds.width / 1.3)
.background(LinearGradient(
gradient: Gradient(
colors: [.buttonGradientStartColor, .buttonGradientEndColor]),
startPoint: .top,
endPoint: .bottom))
// if u want to change swipe menu background color
}
}
我找到了实现此行为的方法,在 HomePageview 中创建状态变量并在菜单中创建绑定变量,这解决了我的问题。