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. 效果图:

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/104471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相似性搜索:第 1 部分- kNN 和倒置文件索引

图片来源&#xff1a;维亚切斯拉夫叶菲莫夫 一、说明 SImilarity 搜索是一个问题&#xff0c;给定一个查询的目标是在所有数据库文档中找到与其最相似的文档。 在数据科学中&#xff0c;相似性搜索经常出现在NLP领域&#xff0c;搜索引擎或推荐系统中&#xff0c;其中需要检索最…

修改克隆虚拟机的静态ip地址

要修改克隆虚拟机的静态IP地址&#xff0c;您需要在虚拟机操作系统内部进行配置。以下是一般步骤&#xff0c;具体步骤可能因您使用的虚拟化平台和操作系统而有所不同。这里以使用VMware虚拟化平台和Windows操作系统为例&#xff1a; 注意&#xff1a;在更改虚拟机的网络设置之…

C# OpenVINO Cls 图像分类

效果 耗时 class idbrown_bear, score0.86 preprocess time: 0.00ms infer time: 2.72ms postprocess time: 0.02ms Total time: 2.74ms项目 代码 using OpenCvSharp; using Sdcb.OpenVINO; using Sdcb.OpenVINO.Natives; using System; using System.Diagnostics; using Sys…

python学习笔记4-二分查找

题目链接 一个List对象可以 ‘.bisect(val)’ 获得大于等于val的最小元素这道题目思想值得看一下 from sortedcontainers import SortedList class Solution:def avoidFlood(self, rains: List[int]) -> List[int]:ans [1] * len(rains)l SortedList() # 可以清空池子…

java基础之数组

数组 数组的本质是一个相同数据类型的元素集合。元素是数组的组成部分&#xff0c;数组中每一个元素都可以使用唯一的索引值来访问&#xff0c;这个索引值也可以叫做数组下标。数组是很多集合类的底层存储结构&#xff0c;在了解java集合类之前大家先了解一下数组吧。 数组初始…

地产三维实景vr展示的功能及特点

随着科技的不断发展&#xff0c;VR(虚拟现实)技术也越来越成熟。VR技术的广泛应用&#xff0c;已经逐渐渗透到各个领域&#xff0c;其中引人注目的就是虚拟展馆。虚拟展馆是一种利用VR技术构建的线上展示空间&#xff0c;让观众可以在家中就能参观展览&#xff0c;带来了极大地…

LCR 172.点名

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;LCR 173. 点名 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 二分找出第一个不是递增 1 的位置即可。 解题代码&#xff1a; class Solution { public:int takeAttendance(vector<in…

模板进阶和反向迭代器

文章目录 模板非类型模板参数模板特化函数模板特化类模板特化 模板分离编译 反向迭代器 模板 非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参&#xff0c…

【Android】关于touch设备TOOL_TYPE_STYLUS

这里通过log来查看触控笔的motionEvent&#xff0c; Overridepublic boolean onTouchEvent(MotionEvent event) {Log.i(tag, "event" event);return true;}Overridepublic boolean onGenericMotionEvent(MotionEvent event) {Log.i(tag, "G event" event…

基于CodeFormer实现图片模糊变清晰,去除马赛克等效果

前言 CodeFormer是一种基于AI技术深度学习的人脸复原模型&#xff0c;由南洋理工大学和商汤科技联合研究中心联合开发。该模型通过结合了VQGAN和Transformer等技术&#xff0c;可以通过提供模糊或马赛克图像来生成清晰的原始图像。可以实现老照片修复、照片马赛克修复、黑白照…

【ARM Coresight 系列文章 9.1 -- ITM 仪器化跟踪宏单元详细介绍】

文章目录 1.1 ITM 介绍1.1.1 ITM 功能介绍1.1.2 Cortex-M ITM 的地址范围1.2 ITM 使用1.2.1 ITM 寄存器介绍1.2.2 Cortex-M7 ITM 代码示例1.2.3 Cortex-M33 ITM 代码示例1.1 ITM 介绍 在debug 调试阶段通常都是使用 printf(printk) 来进行进行 log 输出,然后定位问题。那么如…

排序算法-希尔排序法(ShellSort)

排序算法-希尔排序法&#xff08;ShellSort&#xff09; 1、说明 我们知道当原始记录的键值大部分已排好序的情况下插入排序法非常有效&#xff0c;因为它不需要执行太多的数据搬移操作。希尔排序法是D.L.Shell在1959年7月发明的一种排序法&#xff0c;可以减少插入排序法中数…

安全论坛和外包平台汇总

文章目录 一. 网络安全论坛汇总二. 外包平台汇总1. 国内&#xff1a;2. 国外 一. 网络安全论坛汇总 安全焦点BugTraq&#xff1a;http://www.fuzzysecurity.com/Exploit-DB&#xff1a;https://www.exploit-db.com/hackone&#xff1a;https://www.hackerone.com/FreeBuf&…

保护你的爬虫免受CSRF攻击:深入了解CSRF-Token

CSRF&#xff08;Cross-Site Request Forgery&#xff09;是一种常见的网络攻击类型&#xff0c;可用于伪装用户发起的请求&#xff0c;因此保护你的爬虫免受CSRF攻击至关重要。在本文中&#xff0c;我们将深入探讨CSRF-Token&#xff0c;它在CSRF保护中的作用以及爬虫如何处理…

Java IO流

IO 即 Input / Output &#xff0c;输入输出流。IO流在Java中分为输入流和输出流&#xff0c;而根据数据的处理方式又分为字节流和字符流。 Java IO 流的 40 多个类都是从如下 4 个 抽象类基类中派生出来的。 InputStream /Reader : 所有的输入流的基类&#xff0c;前者是字节…

论文阅读之《Learn to see in the dark》

Learning to See in the Dark-CVPR2018 Chen ChenUIUC&#xff08;伊利诺伊大学厄巴纳-香槟分校&#xff09; Qifeng Chen, Jia Xu, Vladlen Koltun Intel Labs(英特尔研究院) 文章链接&#xff1a;https://arxiv.org/pdf/1805.01934.pdfhttps://arxiv.org/pdf/1805.01934.p…

rust学习Cell、RefCell、OnceCell

背景 Rust 内存安全基于以下规则:给定一个对象 T,它只能具有以下之一: 对对象有多个不可变引用 (&T)(也称为别名 aliasing)对对象有一个可变引用 (&mut T)(也称为可变性 mutability)这是由 Rust 编译器强制执行的。然而,在某些情况下,该规则不够灵活(this r…

Android Studio展示Activty生命周期

前言 本文章以及之后文章的程序版本使用Android Studio 2022.3.1 Patch 1 版本编辑&#xff0c;使用语言为java&#xff0c;最低支持API 27 Android 8.1&#xff0c;构建工具版本如下&#xff1a; 本文章主要是介绍Activty跳转和删除&#xff0c;以备后续使用&#xff0c;所以就…

pxb 使用物理备份恢复数据库

开源软件 Percona Xtrabackup 可以用于对数据库进行备份恢复&#xff0c;本文为您介绍使用 XtraBackup 工具&#xff0c;将 MySQL 物理备份文件恢复至其他主机上的自建数据库。 注意 如果使用透明加密或 Instant DDL 功能&#xff0c;则无法使用物理备份在自建系统上进行恢复…

sql 注入(4), 盲注

sql 注入, 盲注 盲注适合在页面没有任何回显时使用. 测试页面有变化, 但是没有显示任何异常错误等信息. 情景: url: http://192.168.112.200/security/read.php?id1 服务器数据库名: learn一, boolean盲注 # 盲注可能需要一个一个字符去试探, 字符串处理函数经常会用到. 比…