SwiftUI中的侧菜单栏
我想在SwiftUI中创建一个侧菜单栏 //下面是我想用于内容视图的自定义栏视图的代码SwiftUI中的侧菜单栏,swift,swiftui,Swift,Swiftui,我想在SwiftUI中创建一个侧菜单栏 //下面是我想用于内容视图的自定义栏视图的代码 VStack { ZStack { VStack { Button(action: { withAnimation { sidebarShowns.toggle()
VStack {
ZStack {
VStack {
Button(action: {
withAnimation {
sidebarShowns.toggle()
}
}) {
Image(systemName: "line.horizontal.3")
.font(.headline)
}.padding(.leading)
}.frame(maxWidth: .infinity, alignment: .leading)
Text("WeCollab")
.foregroundColor(.white)
.font(.title)
}
.background(Color.purple.edgesIgnoringSafeArea(.top))
}
}
我希望侧菜单栏视图使用此自定义栏,一旦用户点击3条水平线图标,自定义侧菜单栏将在屏幕左侧打开
我希望它能像这样工作,一旦通过点击3条水平线图标打开侧菜单栏,用户就会看到3个按钮,如设置、主和关于我们。一旦用户点击例如about us,about us视图将在iPhone屏幕上完全打开,自定义栏将隐藏,侧菜单将自动关闭。用户将使用后退按钮“此后退按钮使用左V形图标”导航回原始视图
我不希望每个视图上都有自定义栏,也不希望每个视图中都有侧菜单
我希望能够为每个视图使用一个SwiftUI视图文件来实现这一点,该视图将作为侧菜单栏中的按钮链接到每个视图
//我有一些代码的示例,但没有按照我希望的方式工作
import SwiftUI
enum ViewTypesz {
case main
case settings
case aboutUs
}
class SidebarNavigationManagerz : ObservableObject {
@Published var viewType : ViewTypesz = .main
}
struct testView: View {
@State private var sidebarShowns = false
@StateObject var navigationManagers = SidebarNavigationManagerz()
var body: some View {
ZStack(alignment: .topLeading) {
if sidebarShowns {
SidebarView(navigationManagers: navigationManagers)
.frame(width: 250)
.frame(maxHeight: .infinity)
.border(Color.red)
.transition(sidebarShowns ? .move(edge: .leading) : .move(edge: .trailing) )
.background(customBlueColour)
.opacity(60.0)
}
VStack {
ZStack {
VStack {
Button(action: {
withAnimation {
sidebarShowns.toggle()
}
}) {
Image(systemName: "line.horizontal.3")
.font(.headline)
}.padding(.leading)
}.frame(maxWidth: .infinity, alignment: .leading)
Text("WeCollab")
.foregroundColor(.white)
.font(.title)
}
.background(Color.purple.edgesIgnoringSafeArea(.top))
VStack {
switch navigationManagers.viewType {
case .main:
MainView()
case .settings:
SettingsViewz(navigationManagers: navigationManagers)
case .aboutUs:
AboutUsView()
// case .homeview:
// HomeView()
}
}.frame(maxHeight: .infinity)
}.frame(maxWidth: .infinity, maxHeight: .infinity)
} .edgesIgnoringSafeArea(.top)
}
}
struct SidebarView : View {
@ObservedObject var navigationManagers : SidebarNavigationManagerz
var body: some View {
//Sidebar
VStack {
Button(action: { navigationManagers.viewType = .main }) {
Text("Main")
}
Button(action: { navigationManagers.viewType = .settings }) {
Text("Settings")
}
Button(action: { navigationManagers.viewType = .aboutUs }) {
Text("About Us")
}
}
}
}
struct MainView : View {
var body: some View {
Text("Main")
}
}
struct SettingsViewz: View {
@ObservedObject var navigationManagers : SidebarNavigationManagerz
var body: some View {
Text("Settings")
Button("Go home") {
navigationManagers.viewType = .settings
}
}
}
struct AboutUsView : View {
var body: some View {
Text("About Us")
}
}
struct testView_Previews: PreviewProvider {
static var previews: some View {
testView()
}
}
这里有一个链接,指向我找到的一个解决方案,但我无法使它按照我想要的方式工作,但我提供了帮助。
这似乎是你想要的:
enum ViewTypesz {
case main
case settings
case aboutUs
}
class SidebarNavigationManagerz : ObservableObject {
@Published var viewType : ViewTypesz = .main
@Published var sidebarShown = false
func navigateToViewType(_ type: ViewTypesz) {
viewType = type
sidebarShown = false
}
@ViewBuilder var viewForType : some View {
switch viewType {
case .main:
EmptyView()
case .aboutUs:
AboutUsView()
case .settings:
SettingsViewz()
}
}
var bindingForNavLink : Binding<Bool> {
.init { () -> Bool in
return self.viewType != .main
} set: { (newValue) in
if !newValue { self.viewType = .main }
}
}
}
struct ContentView: View {
@StateObject var navigationManagers = SidebarNavigationManagerz()
var body: some View {
NavigationView {
if navigationManagers.viewType != .main {
NavigationLink(destination: navigationManagers.viewForType, isActive: navigationManagers.bindingForNavLink, label: { EmptyView() })
}
VStack(alignment: .leading) {
ZStack {
VStack {
Button(action: {
withAnimation {
navigationManagers.sidebarShown.toggle()
}
}) {
Image(systemName: "line.horizontal.3")
.font(.headline)
}.padding(.leading)
}.frame(maxWidth: .infinity, alignment: .leading)
Text("WeCollab")
.foregroundColor(.white)
.font(.title)
}
.background(Color.purple.edgesIgnoringSafeArea(.top))
ZStack(alignment: .topLeading) {
VStack(alignment: .center) {
MainView()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
if navigationManagers.sidebarShown {
SidebarView(navigationManagers: navigationManagers)
.frame(width: 250)
.frame(maxHeight: .infinity)
.border(Color.red)
.transition(navigationManagers.sidebarShown ? .move(edge: .leading) : .move(edge: .trailing) )
.background(Color.white)
.opacity(60.0)
}
}
}.frame(maxWidth: .infinity, maxHeight: .infinity)
.navigationBarHidden(true)
}.navigationViewStyle(StackNavigationViewStyle())
}
}
struct SidebarView : View {
@ObservedObject var navigationManagers : SidebarNavigationManagerz
var body: some View {
VStack {
Button(action: { navigationManagers.navigateToViewType(.aboutUs) }) {
Text("About us")
}
Button(action: { navigationManagers.navigateToViewType(.settings) }) {
Text("Settings")
}
}
}
}
struct MainView : View {
var body: some View {
Text("Main")
}
}
struct SettingsViewz: View {
var body: some View {
Text("Settings")
}
}
struct AboutUsView : View {
var body: some View {
Text("About Us")
}
}
枚举视图类型{
主箱
案例设置
关于
}
类SidebarNavigationManagerz:ObserveObject{
@已发布的变量viewType:ViewTypesz=.main
@已发布的变量SidebarShowed=false
func navigateToViewType(type:ViewTypesz){
视图类型=类型
侧边栏显示=false
}
@ViewBuilder var viewForType:某些视图{
切换视图类型{
主要案例:
EmptyView()
案例.关于:
AboutUsView()
案例设置:
setingsviewz()
}
}
var bindingForNavLink:绑定{
.init{()->Bool-in
返回self.viewType!=.main
}集合:{(newValue)在
如果!newValue{self.viewType=.main}
}
}
}
结构ContentView:View{
@StateObject变量navigationManagers=SidebarNavigationManagerz()
var body:一些观点{
导航视图{
如果navigationManagers.viewType!=.main{
NavigationLink(目标:NavigationManager.viewForType,isActive:NavigationManager.bindingForNavLink,标签:{EmptyView()})
}
VStack(对齐:。前导){
ZStack{
VStack{
按钮(操作:{
动画片{
navigationManagers.SidebarShowed.toggle()
}
}) {
图像(系统名称:“line.horizontal.3”)
.font(.headline)
}.padding(.leading)
}.frame(最大宽度:。无穷大,对齐:。前导)
文本(“WeCollab”)
.foregroundColor(.白色)
.font(.title)
}
.背景(颜色.紫色.边缘识别安全区域(.top))
ZStack(对齐:。顶部引导){
VStack(对齐:。中心){
MainView()
}
.frame(maxWidth:无穷大,maxHeight:无穷大)
如果显示navigationManagers.sidebar{
侧栏视图(NavigationManager:NavigationManager)
.框架(宽度:250)
.frame(最大高度:。无穷大)
.边框(颜色.红色)
.transition(navigationManagers.SidebarShowed?.move(边:。前导):.move(边:。后导))
.背景(颜色.白色)
.不透明度(60.0)
}
}
}.frame(maxWidth:无穷大,maxHeight:无穷大)
.navigationBarHidden(真)
}.navigationViewStyle(StackNavigationViewStyle())
}
}
结构侧边栏视图:视图{
@观察对象变量导航管理器:SidebarNavigationManagerz
var body:一些观点{
VStack{
按钮(操作:{NavigationManager.navigateToViewType(.aboutUs)}){
文本(“关于我们”)
}
按钮(操作:{NavigationManager.navigateToViewType(.settings)}){
文本(“设置”)
}
}
}
}
结构主视图:视图{
var body:一些观点{
正文(“主要”)
}
}
结构设置视图:视图{
var body:一些观点{
文本(“设置”)
}
}
结构AboutsView:View{
var body:一些观点{
文本(“关于我们”)
}
}
工作原理:
SidebarNavigationManagerz
维护是否显示侧栏以及另一个视图的导航链接是否处于活动状态(通过自定义绑定)导航视图的标题隐藏
NavigationLink
,只有当导航管理器中的视图类型设置为.main
当前有一个过渡我并不热衷于返回到主视图,在主视图中标题不立即可见,但这是您可以关注的细节工作。这应该会让你走上正确的道路@jnpdx也许你能帮上忙。我正在调整给定的代码,它崩溃了,idk为什么。我的设置方式是为我要导航到的每个视图都有一个ui视图文件。以及侧菜单的普通swift文件;侧菜单文件包含视图类型和类SidebarNavigationManagerz。为什么我要设置它,使所有代码都不在一个视图文件中。