SwiftUI 5.0(iOS 17)进一步定制 TipKit 外观让撸码如虎添翼

在这里插入图片描述

概览

在之前 SwiftUI 5.0(iOS 17)TipKit 让用户更懂你的 App 这篇博文里,我们已经初步介绍过了 TipKit 的基本知识。

在这里插入图片描述

现在,让我们来看看如何进一步利用 SwiftUI 对 TipKit 提供的细粒度外观定制技巧,让 Tip 更加“明眸皓齿”。

在本篇博文中,您将学到如下内容:

  • 概览
  • 1. TipKit 温故而知新
  • 2. Tip 外观细粒度定制
  • 3. 完全自己打造 Tip 外观
  • 总结

相信学完本课后,小伙伴们对 TipKit 的内功修为会更加炉火纯青、登峰造极!

那还等什么呢?Let’s go!!!😉


本文对应的视频课在此,欢迎小伙伴们恣意观赏!

SwiftUI 定制 TipKit 外观进一步让撸码如虎添翼


1. TipKit 温故而知新

在前一篇关于 TipKit 的博文中,我们介绍了什么是 TipKit 以及如何在 App 中支持 TipKit 的方法。

这里再回忆一下:创建一个 Tip 很简单,我们只需让类型遵守 Tip 协议即可。

struct FavoriteTip: Tip {var title: Text {Text("收藏最爱的图片").bold()}var message: Text? {Text("将心仪的图片保存到相册中").font(.headline).foregroundStyle(.gray.gradient)}var image: Image? {Image(systemName: "heart")}
}

然后,我们可以通过嵌入和弹出两种不同方法来显示它:

// 嵌入 Tip
struct ContentView: View {let favTip = FavoriteTip()var body: some View {NavigationStack {VStack {TipView(favTip)}.padding().navigationTitle("TitKit演示")}}
}// 弹出 Tip
struct ContentView: View {let favTip = FavoriteTip()var body: some View {NavigationStack {VStack {...}.padding().navigationTitle("TitKit演示").toolbar {ToolbarItem {Image(systemName: "heart").font(.title.weight(.black)).foregroundStyle(.pink.gradient).popoverTip(favTip, arrowEdge: .top)}}}}
}

嵌入和弹出 Tip 的效果如下图所示:

嵌入 Tip

弹出 Tip

如果大家对于默认 Tip 的外观不甚满意怎么办?别急,SwiftUI 还有“妙计”。

2. Tip 外观细粒度定制

Apple 在推出 TipKit 框架的同时也提供了若干修改器方法,我们可以利用它们来进一步调整 Tip 视图的外观。

首先是 tipCornerRadius() 方法,它可以用来调整 Tip 视图边角的弧度:

struct ContentView: View {let favTip = FavoriteTip()@State var addTipRadius = falsevar body: some View {NavigationStack {VStack {TipView(favTip)Toggle(isOn: $addTipRadius) {Text("增加 Tip 边角弧度").font(.title3)}}.padding().navigationTitle("TitKit演示").tipCornerRadius(addTipRadius ? 30 : 10).frame(maxHeight: .infinity).background(.gray.opacity(0.66).gradient).animation(.bouncy, value: addTipRadius)}}
}

值得注意的是:tipCornerRadius 修改器方法和随后介绍的所有 Tip 外观调整方法都会沿着视图继承树向下传递,这意味着顶层的方法会影响内部所有的 Tip 外观。

在这里插入图片描述

接下来是 tipImageSize() 修改器,我们可以用它来调整 Tip 内部图片的尺寸:

NavigationStack {VStack {TipView(favTip)}.tipImageSize(CGSize(width: incImageSize ? 50 : 24, height: incImageSize ? 50 : 24)).frame(maxHeight: .infinity).background(.gray.opacity(0.66).gradient).animation(.bouncy, value: incImageSize)
}

运行效果如下所示:

在这里插入图片描述

最后,我们可以用 tipBackground() 修改器方法来调整 Tip 视图背景的显示样式:

NavigationStack {VStack {TipView(favTip)}.tipBackground(incBackgroundHue ? Material.ultraThick : .thin).frame(maxHeight: .infinity).background(.gray.opacity(0.66).gradient).animation(.bouncy, value: incImageSize)
}

运行的效果不出意料:

在这里插入图片描述

上面我们介绍了一些从宏观上调整 Tip 外观的方法,如果小伙伴们还是觉得捉襟见肘、鸟入樊笼怎么办?

别急,我们还可以“欲穷千里目,更上一层楼”:自己动手“丰衣足食”来 100% “恣意”决定 Tip 该如何显示。

3. 完全自己打造 Tip 外观

为了最大程度满足秃头码农们随心所欲定制 Tip 外观的需求,苹果决定将 Tip 的外观样式化(Styling)以便让我们可以无拘无束定制它们“主题皮肤”。

经常撸 SwiftUI 代码的小伙伴们都知道,在 SwiftUI 中大部分原生视图都有对应的样式(Style),比如按钮、Label、Toggle 等等。视图样式为我们充分定制视图的外观带来了极大的便利。

TipKit 也不例外,我们同样可以利用 tipViewStyle() 修改器来排忧解难:

在这里插入图片描述

为了能够安闲自在的 100% 纯手工打造 Tip 的外观,我们首先需要“由着性子”创建一个遵守 TipViewStyle 协议的类型:

struct PureCustomTipViewStyle: TipViewStyle {func makeBody(configuration: Configuration) -> some View {VStack(alignment: .leading) {HStack(alignment: .bottom) {if let image = configuration.image {image.resizable().aspectRatio(contentMode: .fit).font(.title.weight(.heavy)).frame(width: 25, height: 25).foregroundStyle(.teal).padding().overlay {RoundedRectangle(cornerRadius: 15.0).stroke(.secondary, lineWidth: 3.0)}}Rectangle().frame(width: 3, height: 100).foregroundStyle(.white.gradient)VStack(alignment: .leading) {if let title = configuration.title {title.font(.headline)}if let message = configuration.message {Group {message.font(.subheadline).padding()}.background {RoundedRectangle(cornerRadius: 15.0).foregroundStyle(Material.thin)}}}}HStack {Spacer()ForEach(configuration.actions, id: \.id) { action inButton {action.handler()} label: {Image(systemName: "volleyball.fill").foregroundStyle(.yellow.gradient)action.label()}.fontWeight(.bold).buttonStyle(.borderedProminent)}}}.padding().background {Image("bg").resizable().opacity(0.77)}}
}

接着,为了方便起见我们还可以将上面创建的 Tip 自定义样式融入到 TipViewStyle 自身中去:

extension TipViewStyle where Self == PureCustomTipViewStyle {static var pureCustom: Self {Self.init()}
}

最后在 Tip 视图本身或其上层容器中,我们即可悠然自得的调用 tipViewStyle() 修改器方法来施展改头换面的“黑魔法”啦:

struct ContentView: View {let favTip = FavoriteTip()@State var addTipRadius = false@State var incImageSize = false@State var incBackgroundHue = falsevar body: some View {NavigationStack {VStack {TipView(favTip)Toggle(isOn: $addTipRadius) {Text("增加 Tip 边角弧度").font(.title3)}Toggle(isOn: $incImageSize) {Text("增加 Tip 图片大小").font(.title3)}Toggle(isOn: $incBackgroundHue) {Text("增加 Tip 背景色度").font(.title3)}}.padding().navigationTitle("TitKit演示").tipCornerRadius(addTipRadius ? 30 : 10).tipImageSize(CGSize(width: incImageSize ? 50 : 24, height: incImageSize ? 50 : 24)).tipBackground(incBackgroundHue ? Material.ultraThick : .thin)// 应用我们的自定义 Tip 样式.tipViewStyle(.pureCustom).frame(maxHeight: .infinity).background(.gray.opacity(0.66).gradient).animation(.bouncy, value: addTipRadius).animation(.bouncy, value: incImageSize).animation(.bouncy, value: incBackgroundHue)}}
}

编译运行代码,现在用全身毛孔来感受一下纯手工打造 Tip 界面的愉悦之美吧!

在这里插入图片描述

至此,我们完全掌握了 TipKit 中外观调整与定制的全部技巧,小伙伴们还不赶快发挥天马行空般的想象力打造自己的 Tip 视图吧!棒棒哒!💯


想要系统学习 Swift 语言的小伙伴们,千万不要错过我的《Swift 语言开发精讲》专栏哦,欢迎大家恣意观赏:

在这里插入图片描述

  • Swift 语言开发精讲

总结

在本篇博文中,我们介绍了 SwiftUI 5.0 中从宏观全局调整 Tip 视图显示的几种方式。如果小伙伴们觉得还是不能放开手脚,我们还探讨了如何 100% 纯手工打造自己 Tip 内部布局的方法,包您满意!

感谢观赏,再会!😎

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

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

相关文章

【网关】工业智能网关-02

一 公司简介 保定飞凌嵌入式技术有限公司始于2006年,是一家专注嵌入式核心控制系统研发、设计和生产的高新技术企业,是国内最早专业从事嵌入式技术的企业之一。 经过十几年的发展与积累,公司拥有业内一流的软硬件研发团队,在北京…

基于大模型的智慧零售教育科研平台——技术方案

一、概述 1.1背景 随着数字经济的快速发展和全社会数字化水平的升级,人工智能的积极作用越来越凸显,人工智能与各个行业的深度融合已成为促进传统产业转型升级的重要方式之一。ChatGPT的出现掀起了又一波人工智能发展热潮,人工智能行业发展势…

Linux 深入讲解自动化构建工具

各位大佬好 ,这里是阿川的博客 , 祝您变得更强 个人主页:在线OJ的阿川 大佬的支持和鼓励,将是我成长路上最大的动力 阿川水平有限,如有错误,欢迎大佬指正 Linux一系列的文章(质量分均在93分…

Python魔法之旅-魔法方法(07)

目录 一、概述 1、定义 2、作用 二、应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类型检…

3、css3 手写nav导航条(互相学习)

效果例图&#xff1a; 1、首先呈现的是html代码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…

西藏大学计科改考11408!西藏大学计算机考研考情分析!

西藏大学&#xff08;Tibet University&#xff09;&#xff0c;简称藏大&#xff0c;是西藏自治区所属的综合性大学&#xff0c;是列入教育部直属高校序列的教育部与西藏自治区人民政府合建高校&#xff0c;国家“211工程”重点建设大学&#xff0c;国家“双一流”世界一流学科…

【Linux 网络】网络基础(三)(其他重要协议或技术:DNS、ICMP、NAT)

一、DNS&#xff08;Domain Name System&#xff09; DNS 是一整套从域名映射到 IP 的系统。 1、DNS 背景 TCP/IP 中使用 IP 地址和端口号来确定网络上的一台主机的一个程序&#xff0c;但是 IP 地址不方便记忆。于是人们发明了一种叫主机名的东西&#xff0c;是一个字符串&…

法线方程实现最小二乘拟合(Matlab)

一、问题描述 利用法线方程实现最小二乘拟合。 二、实验目的 掌握法线方程方法的原理&#xff0c;能够利用法线方程完成去一组离散数据点的拟合。 三、实验内容及要求 对于下面的不一致系统&#xff0c;构造法线方程&#xff0c;计算最小二乘以及2-范数误差。 [ 3 − 1 2 …

【SQL学习进阶】从入门到高级应用(九)

文章目录 子查询什么是子查询where后面使用子查询from后面使用子查询select后面使用子查询exists、not existsin和exists区别 union&union alllimit &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f495;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面…

计算机网络——如何保证 TCP 传输的可靠性

TCP 是传输层上的协议&#xff0c;它是可靠的&#xff0c;面向连接的。 概括 1. 设置传输格式&#xff0c;包括分为 TCP 段、使用校验和、使用序列号 2. 数据丢失之后的重传&#xff0c;超时重传、快速重传、SACK 选择确认、D-SACK 重复选择确认 3. 流量控制&#xff0c;控…

研发效能DevOps: Ubuntu 部署 JFrog 制品库

目录 一、实验 1.环境 2.Ubuntu 部署 JFrog 制品库 3.Ubuntu 部署 postgresql数据库 4.Ubuntu 部署 Xray 5. 使用JFrog 增删项目 二、问题 1.Ubuntu 如何通过apt方式部署 JFrog 制品库 2.Ubuntu 如何通过docker方式部署 JFrog 制品库 3.安装jdk报错 4.安装JFrog Ar…

Jenkins常用插件与应用详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 Jenkins是一个平台我们通过安装插件来解决我们想要完成的任务 1、Jenkins常用插件 Allure&#…

如何用ChatGPT上热门:完整使用教程与写作技巧

1. ChatGPT概述修订 ChatGPT是一款基于深度神经网络的语言生成技术&#xff0c;能够协助用户创造出各类高品质的文字材料&#xff0c;适宜广泛的应用场景&#xff0c;如编撰文章、文学创作及社交媒体内容生成。 2. 利用ChatGPT生成热门内容的基本步骤 为了有效利用ChatGPT创作…

python实现——综合类型数据挖掘任务(无监督的分类任务)

综合类型数据挖掘任务 航空公司客户价值分析。航空公司客户价值分析。航空公司客户价值分析。航空公司已积累了大量的会员档案信息和其乘坐航班记录&#xff08;air_data.csv&#xff09;&#xff0c;以2014年3月31日为结束时间抽取两年内有乘机记录的所有客户的详细数据。利用…

苍穹外卖数据可视化

文章目录 1、用户统计2、订单统计3、销量排名Top10 1、用户统计 所谓用户统计&#xff0c;实际上统计的是用户的数量。通过折线图来展示&#xff0c;上面这根蓝色线代表的是用户总量&#xff0c;下边这根绿色线代表的是新增用户数量&#xff0c;是具体到每一天。所以说用户统计…

关系数据库:关系运算

文章目录 关系运算并&#xff08;Union&#xff09;差&#xff08;Difference&#xff09;交&#xff08;Intersection&#xff09;笛卡尔积&#xff08;Extended Cartesian Product&#xff09;投影&#xff08;projection&#xff09;选择&#xff08;Selection&#xff09;除…

鹤城杯 2021 流量分析

看分组也知道考http流量 是布尔盲注 过滤器筛选http流量 将流量包过滤分离 http tshark -r timu.pcapng -Y "http" -T json > 1.json这个时候取 http.request.uri 进一步分离 http.request.uri字段是我们需要的数据 tshark -r timu.pcapng -Y "http&quo…

C++ 混合运算的类型转换

一 混合运算和隐式转换 257 整型2 浮点5 行吗&#xff1f;成吗&#xff1f;中不中&#xff1f; C 中允许相关的数据类型进行混合运算。 相关类型。 尽管在程序中的数据类型不同&#xff0c;但逻辑上进行这种运算是合理的相关类型在混合运算时会自动进行类型转换&#xff0c;再…

【会议征稿】2024年无人驾驶与智能传感技术国际学术会议(ADIST 2024)

2024年无人驾驶与智能传感技术国际学术会议&#xff08;ADIST 2024&#xff09;将于2024年6月28-30日在珠海召开。ADIST 2024旨在搭建学术资源共享平台&#xff0c;加强中外学术合作&#xff0c;促进自动驾驶和智能传感技术的发展&#xff0c;促进全球研究人员、开发人员、工程…