大师学SwiftUI第6章 - 声明式用户界面 Part 3
安全域视图
SwiftUI还内置了创建安全文本框的视图。这一视图会把用户输入的字符替换成点以及隐藏敏感信息,比如密码。
- SecureField(String, text: Binding):该初始化方法创建一个安全输入框。第一个参数定义占位文本,
text参数为存储用户插入值的绑定属性。
实现方式与TextField视图相同,我们也可以应用相同的修饰符,如下所示。
示例6-29:使用安全文本框
struct ContentView: View {@State private var pass: String = ""var body: some View {VStack(spacing: 15) {Text(pass).padding()SecureField("Insert Password", text: $pass).textFieldStyle(.roundedBorder)Spacer()}.padding()}
}
SecureField视图和TextField视图外观一样。唯一的差别是其中的字符是隐藏的。

图6-15:安全文本框
✍️跟我一起做:创建一个多平台项目。使用示例6-29中的代码更新ContentView视图。在输入框中插入字符。会看到字符被替换成为小黑点,如图6-15所示。
文本编辑器视图
SwiftUI还自带一个称为TextEditor的视图让用户可以插入多行文本。以下是该视图的初始化方法。
- TextEditor(text: Binding):此初始化方法创建一个文本编辑器。
text参数是存储用户所插入文本的绑定属性。
该视图可以接收前面用于格式化文本的TextField和Text视图的一些修饰符。例如,我们可以设置视图中文本的对齐、行间距以及是否做错误检查。
示例6-30:实现一个文本编辑器
struct ContentView: View {@State private var text: String = ""var body: some View {TextEditor(text: $text).multilineTextAlignment(.leading).lineSpacing(10).autocorrectionDisabled(true).padding(8)}
}

图6-16:文本编辑器
开关视图
Toggle视图创建一个在两种状态间切换的控件。默认在移动设备上显示为对用户友好的开关,在Mac上显示为复选框。该视图包含如下初始化方法。
- Toggle(String, isOn: Binding):该初始化方法创建一个
Toggle视图。第一个参数定义标签,isOn参数为存储当前状态的绑定属性。本视图还自带有一个由闭包返回视图的标签(Toggle(isOn: Binding, label: Closure))。
该视图要求绑定属性存储当前值。在下例中,我们提供了一个@State属性并使用属性值来选取适当的标签。
示例6-31:实现一个开关
struct ContentView: View {@State private var currentState: Bool = truevar body: some View {VStack {Toggle(isOn: $currentState, label: {Text(currentState ? "On" : "Off")})Spacer()}.padding()}
}
示例6-31中的代码使用三元运算符来检测currentState属性的值并显示相应的文本(On或Off)。默认我们设置属性值为true,因此开关处于打开状态并在屏幕上显示On标签,但如果点击开关,就会关闭,视图更新为显示Off标签。

图6-17:打开和关闭开关
✍️跟我一起做:创建一个多平台项目。使用示例6-31中的代码更新ContentView视图。点击打开或关闭开关。使用这个项目测试下面的例子。
赋值给label参数的闭包可以包含另外一个定义副标题的视图,如下例所示。
示例6-32:添加副标题
struct ContentView: View {@State private var currentState: Bool = truevar body: some View {VStack {Toggle(isOn: $currentState, label: {Text(currentState ? "On" : "Off")Text("Enable or Disable")})Spacer()}.padding()}
}

图6-18:带标题和副标题的开关
Toggle视图创建了一个包含标题和控件中间为弹性空间的横向布局,结果就是整个视图占满容器的横向空间,标签和控件位于两端。如果希望对视图的位置和尺寸做精确控制,可以应用此前介绍过的fixedSize修饰符来降低视图的尺寸,或使用如下修饰符隐藏标签。
- labelsHidden():此修饰符隐藏赋值给控件的标签。
这一修饰符适用于多款控件,但对开关尤为有用。下例展示了如何实现它来为控件定义一个自定义标签。
示例6-33:为Toggle视图定义一个自定义标签
struct ContentView: View {@State private var currentState: Bool = truevar body: some View {HStack {Toggle("", isOn: $currentState).labelsHidden()Text(currentState ? "On" : "Off").padding().background(Color(currentState ? .yellow : .gray))}.padding()}
}
视图现在为控件的大小并在屏幕中心显示。标签不再显示 ,因此我们将其声明为空字符串,但在当前值的侧边包含一个Text视图。

图6-19:自定义大小以及开关的标签
类似Button视图,Toggle视图也实现了修饰符用于定义控件的样式。
- toggleStyle(ToggleStyle):这一修饰符定义开关的样式。参数是一个遵循
ToggleStyle协议的结构体。为创建标准的结构体,框架包含了automatic、button、checkbox和switch这些属性。
默认值为automatic,表示控件的样式由系统选择。如果希望保持同一种样式,可以赋值switch或checkbox(仅能用于Mac)。这些值用于指定标准样式,但框架还内置了button值来创建完全不同类型的控件。在将这一样式赋值给视图时,系统显示一个开关按钮来表示开和关的状态。在按钮处于开的状态时,高亮显示,否则显示 为标准按钮。
示例6-34:实现一个开关按钮
struct ContentView: View {@State private var currentState: Bool = truevar body: some View {HStack {Toggle(isOn: $currentState, label: {Label("Send", systemImage: "mail")}).toggleStyle(.button)}.padding()}
}

图6-20:切换按钮为开关状态
框架提供的样式是有限的,但我们可以自行创建。只需要定义一个遵循ToggleStyle协议的结构体。该协议要求结构体实现如下方法。
- makeBody(configuration: Configuration):该方法定义并返回一个替换开关主体的视图。
configuration参数是一个Configuration类型的值,包含控件相关信息。
这个方法接收一个类型为Configuration的值,是ToggleStyleConfiguration的类型别名,包含如下属性来返回控件相关的信息。
- isOn:该属性返回一个表示开关处于开或关状态的布尔值。
- label:该属性返回定义开关标签的视图。
isOn是一个绑定属性,创建与视图的双向绑定,因此我们可以读取并修改其值来激活或停用控件。在下例中,我们创建了一个类似复选框的Toggle视图。点击控件时,图形变换颜色来表示当前的状态(灰色为停用,绿色为激活)。
示例6-35:定义一个自定义Toggle视图
struct MyStyle: ToggleStyle {func makeBody(configuration: Configuration) -> some View {HStack(alignment: .center) {configuration.labelSpacer()Image(systemName: "checkmark.rectangle.fill").font(.largeTitle).foregroundColor(configuration.isOn ? Color.green : Color.gray).onTapGesture {configuration.$isOn.wrappedValue.toggle()}}}
}struct ContentView: View {@State private var currentState: Bool = falsevar body: some View {VStack {HStack {Toggle("Enabled", isOn: $currentState).toggleStyle(MyStyle())Spacer()}.padding()}}
}
在自定义Toggle视图前必须要考虑几件事。首先,Configuration结构体的label属性包含一个控件当前标签的视图副本,因此如果想要保留这个标签,必须在新的内容中包含这个值。第二,Toggle视图使用HStack视图和标签与控件间的Spacer视图来设计。如果想要保留标准设计,必须保持这种布局。第三,我们负责响应用户的交互以及更新控件的状态,因此必须检测手势并在用户执行手势时通过修改isOn属性的值来变更控件状态。
在示例6-35中,我们定义了一个结构体MyStyle并实现了所要求的makeBody()方法来为Toggle视图提供新设计。为保留标准样式,我们使用HStack视图来包装视图并使用Spacer视图来分隔标签与控件。首先我们读取label属性的值来添加当前标签,然后声明Spacer视图,最后声明一个Image视图来展示外观像复选框的SF图标。为将Image视图转换为控件,我们使用font()修饰符定义其大小,应用foregroundColor()修饰符来根据isOn属性的当前值来修改图标的颜色,最后,使用onTapGesture()修饰符监测用户何时点击Image视图。我们会在第12章中学习更多有关手势修饰符的知识。现在,只需要知道这一修饰符在每次用户点击视图时执行一个闭包。在这个闭包中,我们访问isOn属性的绑定值并通过对wrappedValue属性中的布尔值应用toggle()修饰符切换值。(本例中,绑定值的setter是私有的,因此通过wrappedValue属性访问它,本章前面做过讲解。)这会修改该属性的当前值,进而改变控件的状态,将其打开及关闭。

图6-21:Toggle视图的自定义样式
滑块视图
Slider视图创建一个控件,允许用户选择一个范围内的值。显示为一个带结点的横条,结点对应所选择的值。该结构体包含如下初始化方法。
- Slider(value: Binding, in: Range, step: Float, onEditingChanged: Closure):这个初始化方法创建一个
Slider视图。value参数是希望用于存储当前值的绑定属性,in参数是指定用户选择的最大、最小值范围,step参数表示当前值递增或递减的量,onEditingChanged参数是在用户开始或结束移动滑块时执行的闭包。
要创建滑动,必须至少提供一个@State属性来存储值以及一个决定允许最小和最值的范围。
示例6-36:创建滑块
struct ContentView: View {@State private var currentValue: Float = 5var body: some View {VStack {Text("Current Value: \(currentValue.formatted(.number.precision(.fractionLength(0))))")Slider(value: $currentValue, in: 0...10, step: 1.0)Spacer()}.padding()}
}
示例6-36中的代码创建一个0到10的滑块,以Text视图显示当前值。Slider视图接收类型为Float和Double类型的值,因此允许我们选择浮点值,但我们可以通过声明step参数值为1.0来指定希望用户选择的是整数,如本例所示。(注意我们需要使用第4章中介绍的formatted()方法将Text视图的值格式化为整数。)因为currentValue属性使用数字5进行了初始化,结点的初始位置就位于正中间。

图6-22:整数值滑块
Slider初始化方法还内置了onEdittingChanged参数,接收一个闭包,闭包接收表示用户开始或结束移动滑块的布尔值。我们可以使用它来高亮显示编辑中的值,如下例所示。
示例6-37:响应滑块状态
struct ContentView: View {@State private var currentValue: Float = 5@State private var textAcitve: Bool = falsevar body: some View {VStack {Text("Current Value: \(currentValue.formatted(.number.precision(.fractionLength(0))))").padding().background(textAcitve ? Color.yellow : Color.clear)Slider(value: $currentValue, in: 0...10, step: 1.0, onEditingChanged: { self.textAcitve = $0 })Spacer()}.padding()}
}
示例6-37中的视图包含一个名为textActive的新@State属性。赋值给闭包的onEdittingChanged参数在用户开始移动滑块时对该属性赋值true,释放结点时赋值false。Text视图的background()修饰符读取该值根据当前状态设置不同的背景色。因此,在用户移动滑块时显示当前值的文本为黄色背景,否则没有背景色。
进度视图
SwiftUi内置有ProgressView视图来用于创建进度条。该视图设计用于显示任务的进度。
- ProgressView(String, value: Binding, total: Double):此初始化方法创建一个进度条。第一个参数指定标签,
value参数表示当前进度,total参数指定表示任务完成度的值。(默认值为0.0到1.0)。
视图的实现非常直观。我们只需要一个表示当前进度的属性值。
示例6-38:显示进度
struct ContentView: View {@State private var currentValue: Float = 5var body: some View {VStack {ProgressView(value: currentValue, total: 10)Spacer()}.padding()}
}
这一ProgressView视图值由0.0到10.0,初始值为5(通过currentValue赋了初始值),因此进度位于中心。

图6-24:进度条
ProgressView视图设计用于显示任务即时的进度,比如从服务端下载的当前数据量,或是还差多少完成任务。稍后我们会学习如何执行其中一些任务,但现在我们通过Slider视图来做测试,如下所示。
示例6-39:模拟进度
struct ContentView: View {@State private var currentValue: Float = 5var body: some View {VStack {ProgressView(value: currentValue, total: 10)Slider(value: $currentValue, in: 0...10)Spacer()}.padding()}
}
本例中,我们对Slider和ProgressView设置了相同的值。范围为0到10,因此每当我们移动滑块时,进度条就显示相同值。

图6-25:使用中的进度条
ProgressView结构体内置了如下修饰符用于定义进度条的样式。
- progressViewStyle(ProgressViewStyle):这一修饰符指定
ProgressView视图的颜色 。参数是一个遵循ProgressViewStyle协议的结构体。框架定义了automatic、circular和linear属性来创建标准视图。
默认样式为automatic,表示视图显示为一个线性进度条,但我们可以指定circular值来创建活动指示。这是一个表示任务在处理中的转盘,但不同于进度条,这类指示符没有隐性界限,所示无需指定任何值,如下所示。
示例6-40:显示活动指示器
struct ContentView: View {@State private var currentValue: Float = 5var body: some View {VStack {ProgressView().progressViewStyle(.circular)Spacer()}.padding()}
}

图6-26:活动指示器
其它相关内容请见虚拟现实(VR)/增强现实(AR)&visionOS开发学习笔记
相关文章:
大师学SwiftUI第6章 - 声明式用户界面 Part 3
安全域视图 SwiftUI还内置了创建安全文本框的视图。这一视图会把用户输入的字符替换成点以及隐藏敏感信息,比如密码。 SecureField(String, text: Binding):该初始化方法创建一个安全输入框。第一个参数定义占位文本,text参数为存储…...
使用AI自动生成PPT提高制作效率
使用AI自动生成PPT提高制作效率 在制作PPT方面,很多制作者都会轻易跳进一个怪圈:“我要制作一个关于关爱老人的PPT,该怎么做呢,有模板没有?”这个会涉及很多逻辑需要经过不断的思考,制作PPT要通过很多素材、使用技巧、…...
Servlet中访问网页常遇到的问题
网页出现404 出现这一种情况是浏览器访问的资源不存在 第一种情况通常是路径出错请检查你的路径是否一致 第二种情况确认你的webapp是否被正确加载 smart tomcat由于只加载一个webapp 如果加载失败 就会直接启动失败 拷贝war方式到Tomcat要加载多个webapp如果失败只有日志 查…...
Vue加载序列帧动图
解读方法 使用<img :src"currentFrame" alt"加载中" /> 加载图片动态更改src的值使用 requestAnimationFrame 定时更新在需要的页面调用封装的组件 <LoadToast v-if"showLoading" /> 封装组件 <template><div class"…...
k8s的配置资源管理
1、configmap*:1.2加入新的特征(重点) 2、secret:保存密码,token,保存敏感的k8s资源(保存加密的信息) (1)敏感的k8s资源,这类数据可以直接存放在…...
vue 指定区域可拖拽的限定拖拽区域的div(如仅弹窗标题可拖拽的弹窗)
<template><div class"container" ref"container"><div class"drag-box" v-drag><div class"win_head">弹窗标题</div><div class"win_content">弹窗内容</div></div><…...
【idea】idea插件编写教程,博主原创idea插件已上架idea插件市场 欢迎下载
前言:经常使用Objects.equals(a,b)方法的同学 应该或多或少都会因为粗心而传错参, 例如日常开发中 我们使用Objects.equals去比较 status(入参),statusEnum(枚举), 很容易忘记statusEnum.getCode() 或 statusEnum.getVaule() ,再比…...
探索Python数据结构与算法:解锁编程的无限可能
文章目录 一、引言1.1 数据结构与算法对于编程的重要性1.2 Python作为实现数据结构与算法的强大工具 二、列表和元组2.1 列表:创建列表、索引、切片和常用操作2.2 元组:不可变序列的特性和使用场景 三、字符串操作和正则表达式3.1 字符串的常见操作和方法…...
责任链模式介绍及演示
责任链模介绍 责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,其主要目的是将请求的发送者和接收者解耦。在这个模式中,多个对象有机会处理一个请求,形成一条“责任链”。每个对象在链中检查该请求并…...
智能小程序小部件(Widget)表单组件属性说明+代码明细
在 Tuya MiniApp Tools 中,新建项目并选择小部件(Widget)对应模板即可自动创建小部件(Widget)项目。 button 按钮,用于强调操作并引导用户去点击。 属性说明 属性名类型默认值必填说明sizestringdefault否按钮的大小typestringdefault否按钮的样式类…...
自学Python笔记总结(更新中……)
自学Python笔记总结 网址数据类型类型查看类型,使用type内置类标识符 输出输入语句format函数的语法及用法数据类型的转换运算符算数运算符赋值运算符的特殊场景拆包 比较运算符逻辑运算符 与 短路位运算符运算符优先级 程序流程控制分支语句pass 占位 循环语句 whi…...
十四.变量、异常处理
变量、异常处理 1.变量1.1系统变量1.1.1系统变量分类1.1.2查看系统变量 1.2用户变量1.2.1用户变量分类1.2.2会话用户变量1.2.3局部变量1.2.4对比会话用户变量与局部变量 补充:MySQL 8.0的新特性—全局变量的持久化 2.定义条件与处理程序2.1案例分析2.2定义条件2.3定义处理程序2…...
import { ArrowRight } from “@element-plus/icons-vue“;
今天下午快被这个问题折磨疯了 虽然知道这个问题怎么产生的 但项目里那个碍眼的红线就是去不掉 后来才发现 这是插件的锅 我的心情 你知道我想要说什么的 想必能看到这篇文章的 也知道这个问题是怎么产生的 vue3ts使用的时候 默认是需要带上文件名的 但是引入el组件时 …...
Kubernetes 面试宝典
创建 Pod的主要流程? 客户端提交 Pod 的配置信息(可以是 yaml 文件定义的信息)到 kube-apiserver. Apiserver 收到指令后,通知 controllr-manager 创建一个资源对象 controller-manager 通过 apiserver 将 pod 的配置信息存储到 ETCD 数据中薪心中 kube-scheduler 检查到 p…...
c语言二维数组
系列文章目录 c语言二维数组 c语言二维数组 系列文章目录一、二维数组的定义一、二维数组的内存模型 一、二维数组的定义 int main() {//二维数组的定义int arr[3][4];arr[0][0]; arr[0][1]; arr[0][2]; arr[0][3]; arr[0][4];arr[1][0]; arr[1][1]; arr[1][2]; arr[1][3]; ar…...
ArcGIS Pro 拓扑编辑和常见一些拓扑错误处理
7.4 拓扑编辑 拓扑编辑也叫共享编辑,多个数据修改时,一块修改,如使用数据:chp7\拓扑检查.gdb,数据集DS下JZX、JZD和DK,加载地图框中,在“地图”选项卡下选择“地图拓扑”或“ds_Topology(地理数据库)”&…...
前端踩坑之——antDesignVue的upload组件
本地启动时控制台会报404,放到服务器上控制台会报405(多发一个请求) 原因:upLoad有默认的上传事件 解决:阻止默认事件即可 beforeUpload Hook function which will be executed before uploading. Uploading will be stopped with false or …...
设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户端代码,使得算法的变化不会影响到使用该算法的客户端…...
Ubuntu12.0安装g++过程及其报错
Ubuntu12.0安装g过程及其报错 https://blog.csdn.net/weixin_51286763/article/details/120703953 https://blog.csdn.net/dingd1234/article/details/124029945 2.报错二: [41/80] Building CXX object absl/synchronization/CMakeFiles/graphcycles_internal.di…...
rime中州韵小狼毫 汉语拼音输入方案
教程目录:rime中州韵小狼毫须鼠管安装配置教程 保姆级教程 100增强功能配置教程 在word中,我们可以轻易的给汉字加上拼音,如下👇: 但是,如何单独的输入拼音呢?例如输入 pīn yīn, 再如 zhōn…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
