- import Foundation
- import SwiftUI
-
- //@State private var showBackButton: Bool = true
- //@State private var title: String = "Title" //""
- //@State private var subtitle: String? = "SubTitle" //nil
-
- /// 导航栏标题偏好设置
- struct CustomNavBarTitlePreferenceKey: PreferenceKey{
- static var defaultValue: String = ""
-
- static func reduce(value: inout String, nextValue: () -> String) {
- value = nextValue()
- }
- }
-
- /// 导航栏子标题偏好设置
- struct CustomNavBarSubtitlePreferenceKey: PreferenceKey{
- static var defaultValue: String? = nil
-
- static func reduce(value: inout String?, nextValue: () -> String?) {
- value = nextValue()
- }
- }
-
- /// 导航栏隐藏返回按钮偏好设置
- struct CustomNavBarBackButtonHiddenPreferenceKey: PreferenceKey{
- static var defaultValue: Bool = false
-
- static func reduce(value: inout Bool, nextValue: () -> Bool) {
- value = nextValue()
- }
- }
-
- /// 扩展 View
- extension View{
- /// 保存导航栏标题
- func customNavigationTitle(_ title: String) -> some View{
- preference(key: CustomNavBarTitlePreferenceKey.self, value: title)
- }
-
- /// 保存导航栏子标题
- func customNavigationSubtitle(_ subtitle: String?) -> some View{
- preference(key: CustomNavBarSubtitlePreferenceKey.self, value: subtitle)
- }
-
- /// 保存导航栏是否显示回退键
- func customNavigationBarBackButtonHidden(_ value: Bool) -> some View{
- preference(key: CustomNavBarBackButtonHiddenPreferenceKey.self, value: value)
- }
-
- /// 自定义导航栏选项
- func customNavBarItems(title: String = "", subtitle: String? = nil, backButtonHidden: Bool = false) -> some View{
- self
- .customNavigationTitle(title)
- .customNavigationSubtitle(subtitle)
- .customNavigationBarBackButtonHidden(backButtonHidden)
- }
- }
- import SwiftUI
-
- /// 自定义导航栏视图
- struct CustomNavBarView: View {
- @Environment(\.presentationMode) var presentationMode
- let showBackButton: Bool
- let title: String //""
- let subtitle: String? //nil
-
- var body: some View {
- HStack {
- if showBackButton {
- backButton
- }
- Spacer()
- titleSection
- Spacer()
- if showBackButton {
- backButton
- .opacity(0)
- }
- }
- .padding()
- .accentColor(.white)
- .foregroundColor(.white)
- .font(.headline)
- .background(
- Color.accentColor.ignoresSafeArea(edges: .top)
- )
- }
- }
-
- extension CustomNavBarView{
- /// 返回按钮
- private var backButton: some View{
- Button {
- presentationMode.wrappedValue.dismiss()
- } label: {
- Image(systemName: "chevron.left")
- .padding()
- }
- }
-
- /// 标题视图
- private var titleSection: some View{
- VStack(spacing: 4) {
- Text(title)
- .font(.title)
- .fontWeight(.semibold)
- if let subtitle = subtitle{
- Text(subtitle)
- }
- }
- }
- }
-
- struct CustomNavBarView_Previews: PreviewProvider {
- static var previews: some View {
- VStack {
- CustomNavBarView(showBackButton: true, title: "Title", subtitle: "Subtitle")
- Spacer()
- }
- }
- }
- import SwiftUI
-
- /// 自定义导航栏容器视图
- struct CustomNavBarContainerView<Context: View>: View {
- let context: Context
- @State private var showBackButton: Bool = true
- @State private var title: String = ""
- @State private var subtitle: String? = nil
- init(@ViewBuilder context: () -> Context) {
- self.context = context()
- }
-
- var body: some View {
- VStack(spacing: 0) {
- CustomNavBarView(showBackButton: showBackButton, title: title, subtitle: subtitle)
- context
- .frame(maxWidth: .infinity, maxHeight: .infinity)
- }
- // 监听偏好值
- .onPreferenceChange(CustomNavBarTitlePreferenceKey.self) { value in
- self.title = value
- }
- .onPreferenceChange(CustomNavBarSubtitlePreferenceKey.self) { value in
- self.subtitle = value
- }
- .onPreferenceChange(CustomNavBarBackButtonHiddenPreferenceKey.self) { value in
- self.showBackButton = !value
- }
- }
- }
-
- struct CustomNavBarContainerView_Previews: PreviewProvider {
- static var previews: some View {
- CustomNavBarContainerView {
- ZStack {
- Color.green.ignoresSafeArea()
- Text("Hello world")
- .foregroundColor(.white)
- .customNavigationTitle("Title")
- .customNavigationSubtitle("Subtitle")
- .customNavigationBarBackButtonHidden(true)
- }
- }
- }
- }
- import SwiftUI
-
- /// 自定义导航视图
- struct CustomNavView<Content: View>: View {
- /// 泛型
- let context: Content
-
- init(@ViewBuilder context: () -> Content) {
- self.context = context()
- }
-
- var body: some View {
- NavigationView {
- CustomNavBarContainerView {
- context
- }
- }
- .navigationViewStyle(.stack)
- }
- }
-
- extension UINavigationController{
- open override func viewDidLoad() {
- super.viewDidLoad()
- // 手势识别器交互代理置为 nil,进入下一个导航页面,从左往右滑,能够移除当前页面
- interactivePopGestureRecognizer?.delegate = nil
- }
- }
-
- struct CustomNavView_Previews: PreviewProvider {
- static var previews: some View {
- CustomNavView {
- Color.red.ignoresSafeArea()
- }
- }
- }
- import SwiftUI
-
- /// 自定义导航视图链接下个视图
- struct CustomNavLink<Label: View, Destination: View>: View {
-
- let destination: Destination
- let lable: Label
-
- init(@ViewBuilder destination: () -> Destination, @ViewBuilder label: () -> Label) {
- self.destination = destination()
- self.lable = label()
- }
-
- var body: some View {
- NavigationLink {
- CustomNavBarContainerView {
- destination
- }
- .navigationBarHidden(true)
-
- } label: {
- lable
- }
- }
- }
-
- struct CustomNavLink_Previews: PreviewProvider {
- static var previews: some View {
- // 自定义导航试图
- CustomNavView {
- CustomNavLink {
- Text("Destination")
- } label: {
- Text("CLICK ME")
- }
- }
- }
- }
- import SwiftUI
-
- /// 应用导航栏视图
- struct AppNavBarView: View {
- var body: some View {
- /// 系统默认导航栏
- //defaultNavBavView
- /// 自定义导航栏
- customNavBavView
- }
- }
-
- /// 扩展 View
- extension AppNavBarView{
- /// 系统默认导航栏
- private var defaultNavBavView: some View{
- NavigationView {
- ZStack {
- Color.green
- .ignoresSafeArea()
- NavigationLink {
- Text("Destination")
- .navigationTitle("Title2")
- .navigationBarBackButtonHidden(false)
- } label: {
- Text("Navigate")
- .foregroundColor(.black)
- }
- }
- .navigationTitle("Nav title here")
- }
- }
-
- /// 自定义导航栏
- private var customNavBavView: some View{
- CustomNavView {
- ZStack {
- Color.orange.ignoresSafeArea(edges: .bottom)
- CustomNavLink {
- Text("Destination")
- .customNavBarItems(title: "Second Screen", subtitle: "Subtitle should be showing!!!")
- } label: {
- Text("Navigate")
- }
- }
- .customNavBarItems(title: "New Title", subtitle: "Subtitle", backButtonHidden: true)
- }
- }
- }
-
- struct AppNavBarView_Previews: PreviewProvider {
- static var previews: some View {
- AppNavBarView()
- }
- }