• CustomNavBar 自定义导航栏视图


    1. 创建偏好设置键 CustomNavBarTitlePreferenceKey.swift

    1. import Foundation
    2. import SwiftUI
    3. //@State private var showBackButton: Bool = true
    4. //@State private var title: String = "Title" //""
    5. //@State private var subtitle: String? = "SubTitle" //nil
    6. /// 导航栏标题偏好设置
    7. struct CustomNavBarTitlePreferenceKey: PreferenceKey{
    8. static var defaultValue: String = ""
    9. static func reduce(value: inout String, nextValue: () -> String) {
    10. value = nextValue()
    11. }
    12. }
    13. /// 导航栏子标题偏好设置
    14. struct CustomNavBarSubtitlePreferenceKey: PreferenceKey{
    15. static var defaultValue: String? = nil
    16. static func reduce(value: inout String?, nextValue: () -> String?) {
    17. value = nextValue()
    18. }
    19. }
    20. /// 导航栏隐藏返回按钮偏好设置
    21. struct CustomNavBarBackButtonHiddenPreferenceKey: PreferenceKey{
    22. static var defaultValue: Bool = false
    23. static func reduce(value: inout Bool, nextValue: () -> Bool) {
    24. value = nextValue()
    25. }
    26. }
    27. /// 扩展 View
    28. extension View{
    29. /// 保存导航栏标题
    30. func customNavigationTitle(_ title: String) -> some View{
    31. preference(key: CustomNavBarTitlePreferenceKey.self, value: title)
    32. }
    33. /// 保存导航栏子标题
    34. func customNavigationSubtitle(_ subtitle: String?) -> some View{
    35. preference(key: CustomNavBarSubtitlePreferenceKey.self, value: subtitle)
    36. }
    37. /// 保存导航栏是否显示回退键
    38. func customNavigationBarBackButtonHidden(_ value: Bool) -> some View{
    39. preference(key: CustomNavBarBackButtonHiddenPreferenceKey.self, value: value)
    40. }
    41. /// 自定义导航栏选项
    42. func customNavBarItems(title: String = "", subtitle: String? = nil, backButtonHidden: Bool = false) -> some View{
    43. self
    44. .customNavigationTitle(title)
    45. .customNavigationSubtitle(subtitle)
    46. .customNavigationBarBackButtonHidden(backButtonHidden)
    47. }
    48. }

    2. 创建自定义导航栏视图 CustomNavBarView.swift

    1. import SwiftUI
    2. /// 自定义导航栏视图
    3. struct CustomNavBarView: View {
    4. @Environment(\.presentationMode) var presentationMode
    5. let showBackButton: Bool
    6. let title: String //""
    7. let subtitle: String? //nil
    8. var body: some View {
    9. HStack {
    10. if showBackButton {
    11. backButton
    12. }
    13. Spacer()
    14. titleSection
    15. Spacer()
    16. if showBackButton {
    17. backButton
    18. .opacity(0)
    19. }
    20. }
    21. .padding()
    22. .accentColor(.white)
    23. .foregroundColor(.white)
    24. .font(.headline)
    25. .background(
    26. Color.accentColor.ignoresSafeArea(edges: .top)
    27. )
    28. }
    29. }
    30. extension CustomNavBarView{
    31. /// 返回按钮
    32. private var backButton: some View{
    33. Button {
    34. presentationMode.wrappedValue.dismiss()
    35. } label: {
    36. Image(systemName: "chevron.left")
    37. .padding()
    38. }
    39. }
    40. /// 标题视图
    41. private var titleSection: some View{
    42. VStack(spacing: 4) {
    43. Text(title)
    44. .font(.title)
    45. .fontWeight(.semibold)
    46. if let subtitle = subtitle{
    47. Text(subtitle)
    48. }
    49. }
    50. }
    51. }
    52. struct CustomNavBarView_Previews: PreviewProvider {
    53. static var previews: some View {
    54. VStack {
    55. CustomNavBarView(showBackButton: true, title: "Title", subtitle: "Subtitle")
    56. Spacer()
    57. }
    58. }
    59. }

    3. 创建自定义导航栏容器视图 CustomNavBarContainerView.swift

    1. import SwiftUI
    2. /// 自定义导航栏容器视图
    3. struct CustomNavBarContainerView<Context: View>: View {
    4. let context: Context
    5. @State private var showBackButton: Bool = true
    6. @State private var title: String = ""
    7. @State private var subtitle: String? = nil
    8. init(@ViewBuilder context: () -> Context) {
    9. self.context = context()
    10. }
    11. var body: some View {
    12. VStack(spacing: 0) {
    13. CustomNavBarView(showBackButton: showBackButton, title: title, subtitle: subtitle)
    14. context
    15. .frame(maxWidth: .infinity, maxHeight: .infinity)
    16. }
    17. // 监听偏好值
    18. .onPreferenceChange(CustomNavBarTitlePreferenceKey.self) { value in
    19. self.title = value
    20. }
    21. .onPreferenceChange(CustomNavBarSubtitlePreferenceKey.self) { value in
    22. self.subtitle = value
    23. }
    24. .onPreferenceChange(CustomNavBarBackButtonHiddenPreferenceKey.self) { value in
    25. self.showBackButton = !value
    26. }
    27. }
    28. }
    29. struct CustomNavBarContainerView_Previews: PreviewProvider {
    30. static var previews: some View {
    31. CustomNavBarContainerView {
    32. ZStack {
    33. Color.green.ignoresSafeArea()
    34. Text("Hello world")
    35. .foregroundColor(.white)
    36. .customNavigationTitle("Title")
    37. .customNavigationSubtitle("Subtitle")
    38. .customNavigationBarBackButtonHidden(true)
    39. }
    40. }
    41. }
    42. }

    4. 创建自定义导航视图 CustomNavView.swift

    1. import SwiftUI
    2. /// 自定义导航视图
    3. struct CustomNavView<Content: View>: View {
    4. /// 泛型
    5. let context: Content
    6. init(@ViewBuilder context: () -> Content) {
    7. self.context = context()
    8. }
    9. var body: some View {
    10. NavigationView {
    11. CustomNavBarContainerView {
    12. context
    13. }
    14. }
    15. .navigationViewStyle(.stack)
    16. }
    17. }
    18. extension UINavigationController{
    19. open override func viewDidLoad() {
    20. super.viewDidLoad()
    21. // 手势识别器交互代理置为 nil,进入下一个导航页面,从左往右滑,能够移除当前页面
    22. interactivePopGestureRecognizer?.delegate = nil
    23. }
    24. }
    25. struct CustomNavView_Previews: PreviewProvider {
    26. static var previews: some View {
    27. CustomNavView {
    28. Color.red.ignoresSafeArea()
    29. }
    30. }
    31. }

    5. 创建自定义导航视图链接到下一个视图 CustomNavLink.swift

    1. import SwiftUI
    2. /// 自定义导航视图链接下个视图
    3. struct CustomNavLink<Label: View, Destination: View>: View {
    4. let destination: Destination
    5. let lable: Label
    6. init(@ViewBuilder destination: () -> Destination, @ViewBuilder label: () -> Label) {
    7. self.destination = destination()
    8. self.lable = label()
    9. }
    10. var body: some View {
    11. NavigationLink {
    12. CustomNavBarContainerView {
    13. destination
    14. }
    15. .navigationBarHidden(true)
    16. } label: {
    17. lable
    18. }
    19. }
    20. }
    21. struct CustomNavLink_Previews: PreviewProvider {
    22. static var previews: some View {
    23. // 自定义导航试图
    24. CustomNavView {
    25. CustomNavLink {
    26. Text("Destination")
    27. } label: {
    28. Text("CLICK ME")
    29. }
    30. }
    31. }
    32. }

    6. 创建应用导航栏视图 AppNavBarView.swift

    1. import SwiftUI
    2. /// 应用导航栏视图
    3. struct AppNavBarView: View {
    4. var body: some View {
    5. /// 系统默认导航栏
    6. //defaultNavBavView
    7. /// 自定义导航栏
    8. customNavBavView
    9. }
    10. }
    11. /// 扩展 View
    12. extension AppNavBarView{
    13. /// 系统默认导航栏
    14. private var defaultNavBavView: some View{
    15. NavigationView {
    16. ZStack {
    17. Color.green
    18. .ignoresSafeArea()
    19. NavigationLink {
    20. Text("Destination")
    21. .navigationTitle("Title2")
    22. .navigationBarBackButtonHidden(false)
    23. } label: {
    24. Text("Navigate")
    25. .foregroundColor(.black)
    26. }
    27. }
    28. .navigationTitle("Nav title here")
    29. }
    30. }
    31. /// 自定义导航栏
    32. private var customNavBavView: some View{
    33. CustomNavView {
    34. ZStack {
    35. Color.orange.ignoresSafeArea(edges: .bottom)
    36. CustomNavLink {
    37. Text("Destination")
    38. .customNavBarItems(title: "Second Screen", subtitle: "Subtitle should be showing!!!")
    39. } label: {
    40. Text("Navigate")
    41. }
    42. }
    43. .customNavBarItems(title: "New Title", subtitle: "Subtitle", backButtonHidden: true)
    44. }
    45. }
    46. }
    47. struct AppNavBarView_Previews: PreviewProvider {
    48. static var previews: some View {
    49. AppNavBarView()
    50. }
    51. }

    7. 效果图:

            

  • 相关阅读:
    element ui+vue实现导航栏菜单以及页面跳转
    java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发
    C/C++导航系统
    幂等性解决方案
    JVM内存模型介绍
    IDEA web工程入门笔记
    C# 第五章『面向对象』◆第6节:类的继承
    3. SAP ABAP OData 服务诊断工具 /IWFND/ERROR_LOG 的使用方法
    uView 2.0:uni-app生态的利剑出鞘,引领UI框架新纪元
    0基础学习VR全景平台篇 第101篇:企业版功能-子账号分配管理
  • 原文地址:https://blog.csdn.net/u011193452/article/details/133815852