After exploring SwiftUI for quite a while, one of the most cumbersome things I encounter is to manage multiple kinds of navigation bars in an app.
在探索SwiftUI一段时间之后,我遇到的最麻烦的事情之一是在应用程序中管理多种导航栏。
Thankfully, we have ViewModifier
, which allows you to create your own custom modifiers like .padding()
and .font()
. In this short article, I will show you a common design where a main view and a modal have different navigation bars. In this case, you are managing two separate navigation views.
幸运的是,我们有ViewModifier
,它允许您创建自己的自定义修饰符,例如.padding()
和.font()
。 在这篇简短的文章中,我将向您展示一个通用设计,其中主视图和模式具有不同的导航栏。 在这种情况下,您将管理两个单独的导航视图。
This is how the app looks like:
该应用程序的外观如下:
Firstly, create a new ViewModifier
call NavigationBarModifier
. In this struct
you give it two parameters backgroundColor
and textColor
. Then, extend View
so that you can call the method like .navigationBarColor()
. Here’s the code:
首先,创建一个新的ViewModifier
调用NavigationBarModifier
。 在此struct
,给它两个参数backgroundColor
和textColor
。 然后,扩展View
以便可以调用.navigationBarColor()
类的方法。 这是代码:
extension View {
func navigationBarColor(_ backgroundColor: UIColor?, textColor: UIColor?) -> some View {
modifier(NavigationBarModifier(backgroundColor: backgroundColor, textColor: textColor))
}
}
struct NavigationBarModifier: ViewModifier {
var backgroundColor: UIColor?
var textColor: UIColor?
init( backgroundColor: UIColor?, textColor: UIColor?) {
self.backgroundColor = backgroundColor
UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: textColor ?? .black]
UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: textColor ?? .black]
}
func body(content: Content) -> some View {
ZStack{
content
VStack {
GeometryReader { geometry in
Color(self.backgroundColor ?? .clear)
.frame(height: geometry.safeAreaInsets.top)
.edgesIgnoringSafeArea(.top)
Spacer()
}
}
}
}
}
Next, create the two navigation bars with different background colors like this:
接下来,创建具有不同背景颜色的两个导航栏,如下所示:
struct RedNavigationBar: ViewModifier {
var title: String
func body(content: Content) -> some View {
content
.navigationBarColor(.red, textColor: .white)
.navigationBarTitle(title)
}
}
struct GreenNavigationBar: ViewModifier {
var title: String
func body(content: Content) -> some View {
content
.navigationBarColor(.green, textColor: .blue)
.navigationBarTitle(title)
}
}
And finally, you can insert the navigation bar modifiers by calling .modifier()
like this:
最后,您可以通过调用.modifier()
来插入导航栏修饰符,如下所示:
struct ModalView: View {
var body: some View {
NavigationView {
VStack {
Spacer()
Text("ModalView")
Spacer()
}.modifier(RedNavigationBar(title: "Modal"))
}
}
}
struct ContentView: View {
@State var presentedModal = false
var body: some View {
NavigationView {
VStack {
Spacer()
Spacer()
Text("ContentView")
Spacer()
Button(action: {
self.presentedModal = true
}) {
Text("Present Modal")
}
Spacer()
Spacer()
}
.modifier(GreenNavigationBar(title: "Content"))
.sheet(isPresented: $presentedModal) {
ModalView()
}
}
}
}
Essentially, make sure you are managing as little NavigationViews
as possible in SwiftUI. Having multiple NavigationViews
increases the complexity of your UI when trying to modify each bar in every single view.
本质上,请确保您在SwiftUI中尽可能少地管理NavigationViews
。 尝试修改每个单个视图中的每个栏时,拥有多个NavigationViews
增加UI的复杂性。
Additionally, whether you extend from View
or create custom ViewModifiers
to modify your views, that’s your personal preference. Apple has given us a wider spectrum of ways to manage SwiftUI views and let’s use them wisely.
此外,无论您是从View
扩展还是创建自定义ViewModifiers
来修改视图,这都是您的个人喜好。 苹果为我们提供了广泛的管理SwiftUI视图的方法,让我们明智地使用它们。
翻译自: https://medium.com/swlh/managing-multiple-navigationbars-in-swiftui-6957e51c6e86