自定义 NavigationView 顶栏
Posted
技术标签:
【中文标题】自定义 NavigationView 顶栏【英文标题】:Custom NavigationView top bar 【发布时间】:2021-03-12 13:54:35 【问题描述】:我想创建一个类似于上图的设计。为了创建底部的 TabView,我使用了以下代码:
import SwiftUI
struct ParentTabView: View
var body: some View
TabView
HomeView()
.tabItem
Image(systemName: "star.fill")
Text("Home")
Text("Second Tab")
.tabItem
Image(systemName: "star.fill")
Text("Discover")
Text("Third Tab")
.tabItem
Image(systemName: "star.fill")
Text("Settings")
和主视图
struct HomeView: View
var body: some View
NavigationView
Text("Home")
.navigationBarItems(
trailing:
Button(action:
)
Image(systemName: "plus")
)
.navigationTitle("Home")
我遇到的问题是顶部导航栏,因为我无法编辑 NavigationView 以接收标题下方的其他视图。我可以设置标题并添加“加号”按钮,但不能编辑整个顶栏。
可以以这种方式自定义 NavigationView,如果不能,我如何在保持 NavigationView 提供的优势(例如 NavigationLinks 等)的同时实现该结果。
【问题讨论】:
【参考方案1】:Apple 提供的 NavigationBar 不能完全自定义。您可能希望为此用例创建自定义导航栏。
幸运的是,我有一些时间,所以我创建了一个简单的可重复使用的导航栏,看起来像您想要的结果,请看下面。
您必须隐藏 Apple 的导航栏,并将自定义导航栏作为覆盖添加到您的导航视图(如下图所示):
这是可重用自定义导航视图的代码:
enum CustomNavigationBarItem: String, CaseIterable
case dashboard = "Dashboard"
case feed = "Feed"
case followers = "Followers"
struct CustomNavigationBar: View
var title: String
var items: [CustomNavigationBarItem]
@Binding var selectedItem: CustomNavigationBarItem
var buttonAction: () -> ()
var body: some View
VStack
VStack(spacing: 10)
CustomNavigationBarHeader(title: title, buttonAction: buttonAction)
HStack(spacing: 0)
ForEach(items, id: \.self) item in
CustomNavigationBarItemView(text: item.rawValue, isSelected: selectedItem == item)
.onTapGesture
selectedItem = item
.background(Color(#colorLiteral(red: 0.1036974415, green: 0.1036974415, blue: 0.1036974415, alpha: 1)).edgesIgnoringSafeArea(.all))
Spacer()
struct CustomNavigationBarItemView: View
var text: String
var isSelected: Bool
var body: some View
Text(text)
.foregroundColor(isSelected ? .blue : Color(#colorLiteral(red: 0.501960814, green: 0.501960814, blue: 0.501960814, alpha: 1)))
.frame(maxWidth: .infinity)
.padding(.vertical, 10)
.padding(.horizontal, 6)
.overlay(
VStack
Spacer()
Color.blue
.frame(height: 2)
.opacity(isSelected ? 1 : 0)
.animation(.default)
)
struct CustomNavigationBarHeader: View
var title: String
var buttonAction: () -> ()
var body: some View
HStack
Text(title)
.font(.title)
.bold()
Spacer()
Button(action: buttonAction, label:
Image(systemName: "plus")
)
.font(.headline)
.padding(.horizontal)
首页查看代码:
struct HomeView: View
@State private var selectedNavigationBarItem: CustomNavigationBarItem = .dashboard
@State private var numPlusButtonClicked: Int = 0
var body: some View
NavigationView
VStack
Text("Home")
switch selectedNavigationBarItem
case .dashboard:
Text("Currently Showing: Dashboard") //Use your view here
case .feed:
Text("Currently Showing: Feed") //Use your view here
case .followers:
Text("Currently Showing: Followers") //Use your views here
Text("Plus Button Clicked \(numPlusButtonClicked) times.")
.navigationBarHidden(true)
.overlay(
CustomNavigationBar(title: "Home",
items: [.dashboard, .feed, .followers],
selectedItem: $selectedNavigationBarItem)
numPlusButtonClicked += 1 // Code executed when the "+" button gets called
)
注意事项:
-
您可以向“CustomNavigationBarItem”枚举添加更多项目
这绝不是一个完美的组件,因此请随意修改它以满足您的需求:D
祝你好运!
编辑:为 HomeView 添加代码
【讨论】:
这太不可思议了。我感激不尽! 不客气!我很高兴你喜欢它。我已经更新了我的答案以包含 HomeView 的代码以上是关于自定义 NavigationView 顶栏的主要内容,如果未能解决你的问题,请参考以下文章
如何为 NavigationView 中的项目设置自定义字体?
NavigationView中的SwiftUI自定义动画过渡?
如何在 NavigationView 中自定义项目背景和项目文本颜色?