CustomNavBar 自定义导航栏视图
1. 创建偏好设置键 CustomNavBarTitlePreferenceKey.swift
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? = nilstatic func reduce(value: inout String?, nextValue: () -> String?) {value = nextValue()}
}/// 导航栏隐藏返回按钮偏好设置
struct CustomNavBarBackButtonHiddenPreferenceKey: PreferenceKey{static var defaultValue: Bool = falsestatic 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)}
}
2. 创建自定义导航栏视图 CustomNavBarView.swift
import SwiftUI/// 自定义导航栏视图
struct CustomNavBarView: View {@Environment(\.presentationMode) var presentationModelet showBackButton: Boollet title: String //""let subtitle: String? //nilvar body: some View {HStack {if showBackButton {backButton}Spacer()titleSectionSpacer()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()}}
}
3. 创建自定义导航栏容器视图 CustomNavBarContainerView.swift
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? = nilinit(@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 inself.title = value}.onPreferenceChange(CustomNavBarSubtitlePreferenceKey.self) { value inself.subtitle = value}.onPreferenceChange(CustomNavBarBackButtonHiddenPreferenceKey.self) { value inself.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)}}}
}
4. 创建自定义导航视图 CustomNavView.swift
import SwiftUI/// 自定义导航视图
struct CustomNavView<Content: View>: View {/// 泛型let context: Contentinit(@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()}}
}
5. 创建自定义导航视图链接到下一个视图 CustomNavLink.swift
import SwiftUI/// 自定义导航视图链接下个视图
struct CustomNavLink<Label: View, Destination: View>: View {let destination: Destinationlet lable: Labelinit(@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")}}}
}
6. 创建应用导航栏视图 AppNavBarView.swift
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()}
}
7. 效果图:

相关文章:
CustomNavBar 自定义导航栏视图
1. 创建偏好设置键 CustomNavBarTitlePreferenceKey.swift import Foundation import SwiftUI//State private var showBackButton: Bool true //State private var title: String "Title" //"" //State private var subtitle: String? "SubTitl…...
canal rocketmq
上篇文章canal 消费进度说到直接使用ClusterCanalConnector并发消费是有问题的,可以先用单点将canal事件发送到mq中,再由mq并发处理,另外mq还可以做到削峰的作用,让canal数据不至于阻塞。 使用队列,可以自己起一个单实…...
【数据库系统概论】第九章关系查询处理何查询优化
9.1查询处理 一:查询处理步骤 关系数据库管理系统查询处理可以分为4个阶段: 查询分析查询检查查询优化查询执行 (1)查询分析 任务:对查询语句进行扫描,分析词法、语法是否符合SQL语法规则 如果没有语…...
bp盐丘模型波场数值模拟matlab
波场数值模拟是地震勘探和地震学研究中常用的工具,而BP(Backpropagation)盐丘模型是一种用于地下介质成像的方法。如果您想在MATLAB中进行波场数值模拟,并结合BP盐丘模型进行地下成像,可以按照以下步骤进行:…...
结构体对齐规则
1.第一个成员在结构体变量偏移量为0的地址处。 2.其他成员变量对齐到某个数字(对齐数)的整数倍的地址处。(对齐数编译器默认的一个对齐数与该成员大小的较小值)注意:目前有且只有VS编译器有默认为8. 3.结构体总大小为最大对齐数的整数倍。 4.如果嵌套…...
css 如何让元素内部文本和外部文本 一块显示省略号
实际上还是有这样的需求的 <div class"container"><span>啊啊啊啊啊啊啊啊</span>你好啊撒撒啊撒撒撒撒啊撒撒撒撒撒说</div>还是有这样的需求的哦。 div.container {width: 200px;white-space: nowrap;text-overflow: ellipsis;overflow:…...
SQL语句-中级
一、Mysql软件使用 1.启动/停止Mysql服务器 任务管理器 cmd命令:以管理员的身份打开cmd命令行 net start mysql80//开启net stop mysql80//停止 2.连接与断开Mysql服务器 注意要在bin目录下执行:-u用户名root,-p密码 mysql -u root -p 可能出现的…...
巧用h2-database.jar连接数据库
文章目录 一 、概述二、实践三、解决办法 一 、概述 H2 Database是一个开源的嵌入式数据库引擎,采用java语言编写,不受平台的限制,同时H2 Database提供了一个十分方便的web控制台用于操作和管理数据库内容。H2 Database还提供兼容模式&#…...
136.只出现一次的数字
136. 只出现一次的数字 - 力扣(LeetCode) 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题,且…...
mysql中遇到查询字段的别名与函数冲突问题
比如以下哎,我查询城市行业数量排名 select City, DENSE_RANK() over(ORDER BY COUNT(Id) DESC) rank, COUNT(Id) num,IndustrySubGroupName from base_companyinfo WHERE IndustrySubGroupName工业机器人 GROUP BY City 上面使用 DENSE_RANK() 函数来计算排名&am…...
直播获奖
题目描述 NOI2130 即将举行。为了增加观赏性, CCF 决定逐一评出每个选手的成 绩,并直播即时的获奖分数线。本次竞赛的获奖率为 𝑤% ,即当前排名前 𝑤% 的选手的最低成绩就是即时的分数线。 更具体地,…...
选择适合自身业务的HTTP代理有哪些因素决定?
相信对很多爬虫工作者和数据采集的企业来说,如何选购适合自己业务的HTTP代理是一个特别特别困扰的选题,市面上那么多HTTP代理厂商,好像这家有这些缺点,转头又看到另外一家的缺点,要找一家心仪的仿佛大海捞针。今天我们…...
1.3 do...while实现1+...100 for实现1+...100
思路:两个变量,一个变量存储数据之和,一个变量实现自增就行 do...while int i, s;i 1;s 0;do{s 1;i;} while (i < 100);cout << s << endl; for int i, j0;for (i 1; i < 100; i){j 1;}cout << j << …...
react数据管理之setState与Props
react数据管理之setState与Props setState调用原理 setState 是 React 中用于更新组件状态(state)的方法。它的调用原理可以分为以下几个步骤: 状态的改变:当调用 setState 时,React 会将新的状态对象与当前状态对象…...
如何保护我们的网络安全
保护网络安全是至关重要的,尤其是在今天的数字化时代。以下是一些保护网络安全的基本步骤: 1、使用强密码:使用包含字母、数字和特殊字符的复杂密码。不要在多个网站上重复使用相同的密码。定期更改密码。 2、启用双因素认证 (2FA)ÿ…...
springboot 制造装备物联及生产管理ERP系统
springboot 制造装备物联及生产管理ERP系统 liu1113625581...
Google zxing 生成带logo的二维码图片
环境准备 开发环境 JDK 1.8SpringBoot2.2.1Maven 3.2 开发工具 IntelliJ IDEAsmartGitNavicat15 添加maven配置 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.0</version> </…...
使用Python计算平面多边形间最短距离
要计算平面多边形间的最短距离,首先需要导入Excel表格中的多边形数据,然后使用GJK(Gilbert-Johnson-Keerthi)算法来判断两个多边形是否重叠。如果两个多边形不重叠,可以计算它们之间的最短距离。 以下是一个基本的Pyt…...
【Python】Python语言基础(中)
第十章 Python的数据类型 基本数据类型 数字 整数 整数就是整数 浮点数 在编程中,小数都称之为浮点数 浮点数的精度问题 print(0.1 0.2) --------------- 0.30000000000000004 1.可以通过round()函数来控制小数点后位数 round(a b),则表示…...
观察者模式、订阅者发布者模式、vtk中的观察者模式
文章目录 什么是观察者模式vtk是如何实现的观察者模式.AddObserver什么时候使用观察者模式?什么使用订阅发布者模式?观察者模式的实现订阅发布者的实现总结知识补充: 什么是观察者模式 用于在对象之间建立一对多的依赖关系,当一个对象的状态发生变化时…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
