简体   繁体   English

SwiftUI: NavigationView 属性是否需要复制粘贴到每个View 中?

[英]SwiftUI: do NavigationView attributes needs to be copy-pasted in each View?

I have a NavigationStack that I use to move between Views in my iOS app that has some modifications done on the toolbar (Color, colorScheme, toolbar items).我有一个 NavigationStack,用于在我的 iOS 应用程序的视图之间移动,该应用程序在工具栏上进行了一些修改(颜色、颜色方案、工具栏项目)。

To keep the same appearance on all the different views I have to define again all the different attributes in each View I reach using NavigationLinks.为了在所有不同的视图上保持相同的外观,我必须在使用 NavigationLinks 到达的每个视图中再次定义所有不同的属性。

Is there a way to keep what I defined in the top NavigationView across all the different views?有没有办法在所有不同的视图中保留我在顶部 NavigationView 中定义的内容?

Code snippet below:下面的代码片段:

First View where I define the NavigationStack首先查看我定义 NavigationStack 的位置

NavigationStack
        {
            VStack{
             ...
            }
            .navigationTitle("Lavorazioni")
            .navigationBarTitleDisplayMode(NavigationBarItem.TitleDisplayMode.large)
            .toolbarBackground(.blue, for: .navigationBar)
            .toolbarBackground(.visible, for: .navigationBar)
            .toolbarColorScheme(.dark, for: .navigationBar)
            .toolbar {
                Button {
                    mostraProfilo.toggle()
                } label: {
                    Label("User Profile", systemImage: "person.crop.circle")
                }
            }

Second View reached by NavigationLink in VStack VStack 中 NavigationLink 到达的第二个视图

var body: some View {
        VStack{
            ...
        }
        .navigationTitle("Selezione tipologia")
        .toolbarBackground(.blue, for: .navigationBar)
        .toolbarBackground(.visible, for: .navigationBar)
        .toolbarColorScheme(.dark, for: .navigationBar)
        .toolbar {
                Button {
                    mostraProfilo.toggle()
                } label: {
                    Label("User Profile", systemImage: "person.crop.circle")
                }
            }
    }

Is there a way to avoid copypasting every time the following?有没有办法避免每次都复制粘贴?

.toolbarBackground(.blue, for: .navigationBar)
        .toolbarBackground(.visible, for: .navigationBar)
        .toolbarColorScheme(.dark, for: .navigationBar)
        .toolbar {
                Button {
                    mostraProfilo.toggle()
                } label: {
                    Label("User Profile", systemImage: "person.crop.circle")
                }
            }

You can create a custom ViewModifier that holds all your common toolbar modifiers.您可以创建一个自定义ViewModifier来保存所有常用的工具栏修饰符。

struct MyToolbar: ViewModifier{
    //Use shared router
    @EnvironmentObject var viewRouter: MyViewRouter
    //Add unique title for each instance
    let title: String
    func body(content: Content) -> some View {
        content
            .navigationTitle(title)
            .navigationBarTitleDisplayMode(.large)
            .toolbarBackground(.blue, for: .navigationBar)
            .toolbarBackground(.visible, for: .navigationBar)
            .toolbarColorScheme(.dark, for: .navigationBar)
            .toolbar {
                Button {
                    viewRouter.mostraProfilo.toggle()
                } label: {
                    Label("User Profile", systemImage: "person.crop.circle")
                }
            }
    }
}

You can share common navigation actions with the use of a ViewRouter that is accessible to all.您可以使用所有人都可以访问的ViewRouter共享常见的导航操作。

The portfolio Button is a good example.投资组合Button就是一个很好的例子。

///Router to share navigation
class MyViewRouter: ObservableObject{
    //Shared portfolio variable
    @Published var mostraProfilo: Bool = false
    //You can also add things like a `NavigationPath` to make navigation easier.
    
    enum ViewOptions: String, Hashable{
        //Create a case for each view
        case something
        case somethingDifferent
        //Set the title for a view
        var title: String{
            switch self{
            case .something:
                return "Something Title"
            case .somethingDifferent:
                return "different"
            }
        }
        //List the views for each option
        @ViewBuilder var view: some View {
            switch self{
            case .somethingDifferent:
                VStack{
                    Text("something different")
                }
                //Add individually
                .modifier(MyToolbar(title: "different"))
                //View specific modifiers over the common toolbar for overridding 
                .navigationBarTitleDisplayMode(.inline)
                .toolbarBackground(.red, for: .navigationBar)

            case .something:
                VStack{
                    Text("something")
                }
                //Add individually
                .modifier(MyToolbar(title: "something"))
            }
        }
    }
}

Your View s can then use these shared Options and modifiers.然后,您的View可以使用这些共享的Options和修饰符。

struct SharedNavigationModifiers: View {
    @StateObject var viewRouter: MyViewRouter = .init()
    var body: some View {
        NavigationStack{
            VStack{
                NavigationLink("go somewhere", value: MyViewRouter.ViewOptions.something)
                NavigationLink("different", value: MyViewRouter.ViewOptions.somethingDifferent)
            }
            //Everone can display this portfolio using the Router
                .navigationDestination(isPresented: $viewRouter.mostraProfilo) {
                    Text("Portfolio View")
                    //Add to each View
                    .modifier(MyToolbar(title: "portfolio"))
                }
                .navigationDestination(for: MyViewRouter.ViewOptions.self) { option in
                        option.view
                    //Add to all options for a more standard look or individually (See Options)
                        //.modifier(MyToolbar(title: option.title))
                    
                }
        }
        //Inject router so all `View`s in Stack have access
        .environmentObject(viewRouter)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 navigationView、SwiftUI 上创建一个视图 - Create a view over navigationView, SwiftUI 如何从父视图中关闭 SwiftUI NavigationView - How to dismiss a SwiftUI NavigationView from a parent view 如何在 NavigationView (SwiftUI) 启动时显示详细视图 - How to display a detailed view on startup for a NavigationView (SwiftUI) 如何检测返回到 SwiftUI 中 NavigationView 的根视图? - How to detect return to the root view of the NavigationView in SwiftUI? SwiftUI 视图在同一 NavigationView 中更新 NavigationLinks 时崩溃 - SwiftUI view crashes when updating NavigationLinks in same NavigationView SwiftUI - 有没有办法在没有 NavigationView 的情况下构建动态列表视图? - SwiftUI - Is there any way to build a dynamic list view without NavigationView? iOS SwiftUI - NavigationView NavigationLink:使用自定义按钮关闭视图 - iOS SwiftUI - NavigationView NavigationLink: Close view with custom Button 在 SwiftUI 中更改具有 NavigationView 和 ScrollView 的 TabView 内视图的背景颜色 - Change background color of View inside TabView having NavigationView and ScrollView in SwiftUI SwiftUI:如何确定视图是在 NavigationView、Sheet 中呈现还是在根目录中? - SwiftUI: How can I determine if a view is presented in a NavigationView, Sheet, or is the root? 如何在 SwiftUI 中没有 NavigationButton 的情况下导航到 NavigationView 中的另一个视图? - How to navigate to another view in NavigationView without NavigationButton in SwiftUI?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM