SwiftUI学习
SwiftUI学习
swiftUI介绍
- 基于swift语言的全新界面框架
- 声明式语法,swiftUI将其自动转化为可以工作的高效代码
- 复制编辑UI更有效率
- 及时预览,与代码保持同步
SwiftUI与UIKit
UIKit使用的是类,不是结构体
结构体比类更简单且更快,但这仅是swiftUI使用结构体的一小部分原因
UIKit中每个视图都来自UI view的类,继承
swiftUI中所有使用的视图都是琐碎的结构,几乎可以自由使用
程序界面
1.基础框架
import SwiftUI//导入框架
//ContentView符合swiftUI视图协议
//是在屏幕绘制任何东西都必须都必须采用的基本协议
struct ContentView: View {
var body: some View {
Text("Hello,Swift!")
}//一个限制some view指定body类型需要body返回一个遵循了view协议的一个具体实现,它始终是同一种观点,当你无法返回一种类型,再换另一种。
}
//专门供Xcode使用以显示浏览UI设计和代码
struct ContentView_Previews:
PreviewProvider {
static var previews: some View{
ContentView()
}//只会影响画布显示布局,不会影响实际程序运行
}
2.创建视图
1)Form表单
静态控件(如文本和图像)的滚动列表,还可以包括用户交互控件,例如文本字段切换,切换按钮,还可以用来包装表单中的默认文本视图。
疑问:视频中说只能放10个,超过需要Group但是我超过10个没有报错
Section将表格分成几部分
2) 添加导航栏,提供标题
滚动查看时,表单会被遮住
NavigationView添加导航栏,导航栏可以包含标题和按钮
.navigationTitle设置导航栏标题,图中使用的文本视图,也可以直接使用字符串
用户界面顶部的空间就是我们的导航栏
标题加粗字号更大,往上滚动导航栏居中显示小字号标题
.navigationBarTitleDisplayMode()可以改变导航栏标题的对齐方式
3) 按钮
一个显示Tapcount和点击次数的按钮,每点击一次,就计数加一。
因为 ContentView 是一个结构体,是以常量方式创建。它是 immutable 的,不能改变值。因此,当创建了结构体属性,如果你想要在方法中改变这些属性,你需要在方面前面添加 mutating 关键字,例如 mutating func doSomeWork()。但是,Swift 不允许我们创建可变的计算属性,因此我们不能写 mutating var body: some View,这是不允许的。
修改程序状态
属性包装器
@state可以解决限制,允许swiftUI单独储存在可以修改的地方
@State是专门为存储在一个视图中的简单属性而设计的。因此,苹果建议我们向这些属性添加私有访问控制。
在SwiftUI中,修改状态通常涉及到使用@State属性包装器修饰的变量。当这些变量的值改变时,SwiftUI会自动重新渲染界面以反映新的状态。
4) 用户可以输入的文本框
SwiftUI的 @State 属性包装器让我们可以自由地修改视图结构体,这意味着当程序状态改变时,我们可以更新属性值来匹配状态。
TextField()
视图是它们状态的函数。文本框只能反映你的程序中存储的某个值。SwiftUI 期望我们的结构体中有一个字符串属性,以便用于显示文本框的内容。
绑定状态到UI控件
添加一个 name 属性,然后用它然后创建文本框。 Swift 还需要匹配 name 属性到用户输入文本框的内容,但Swift 对于“展示属性的值” 和 “展示属性的值,并且把任何改变写回属性” 的处理是有区别的。我们需要保证文本框里的字符串跟 name 属性里的字符串始终保持一致。“双向绑定”:我们绑定文本框以便它展示我们的属性值,同时我们也绑定属性以便文本框有任何变化时属性也随之更新。在 Swift 中,我们用一种特殊的符号标记这种双向绑定,在属性前写一个$符号。它告诉 Swift 不仅需要读取属性的值,也需要在绑定对象的内容改变时,把值写回属性。注意,在静态文本控件里,你只需要用 name 而不是 符号,记得它创建了一个双向绑定:属性的值既被读取,也被写入。
5) ForEach循环
表单从Row 0到Row99
6) Picker控件
显示各种选项供用户选择
选择器与学生双向绑定,开始显示为0,但随着用户移动选择器,而更新属性
不知道为什么用不了第一个参数
3.堆栈
引入:当创建两个Text View,这种代码根本不允许查看文本,只能显示前一个文本,swift要保证完全是一种视图。
这就是堆栈进入的地方,它们允许我们说这是两个文本视图。
1)VStack 垂直
默认情况下,V堆栈在两个文本视图之间几乎没有间距,但是我们可以像创建堆栈一样通过提供参数来控制间距
改变对齐方式属性,默认情况是居中对齐
左侧对齐
Spacer()
将视图推到边缘:通过将Spacer()与对齐结合使用,可以将视图推送到屏幕顶部底部
2)HStack 水平
与VStack的语法相同
3)ZStack 深度排列内容
两个文本视图,会使视图重叠
内容从上到下,从后到前
4)设置红色背景
.background(Color.red)只有textview具有背景色,它移动到其他位置也不会有任何区别
填充整个区域,应该颜色放入Z堆栈,视为整个视图本身,在文本前涂成红色
颜色可以像形状文本一样使用并自动占用可获得的空间
使用frame设置特定尺寸
上下部分空间有意留白,因为苹果不希望重要的内容会被其他UI功能或者任何圆角遮盖。其他部分为安全距离
使用Color.red.edgesIgnoringSafeArea(.all)将边缘填充
但是不要将任何重要内容放置在安全区域之外,用户可能看不到一些视图
4.其他
1)渐变色
由几种成分和颜色矩阵以显示尺寸和方向信息
梯度类型
线性梯度沿一个方向,我们提供一个起点和一个终点
径向渐变从内到外进行圆形渐变,指定起点和终点半径距颜色圆心的距离
角度梯度,或称圆锥形渐变,使颜色围绕圆形而不是圆形向外辐射
2) 设置按钮图标
Button("Edit"){
print("Button was tapped")
}
Button(action: {
print("Button was tapped")
}){
Text("Edit")
}
使用Image加载iOS内置的铅笔图标
与堆栈结合创造更高级的按钮
3)通知用户
使用一个包含标题信息和一个或两个按钮的弹出窗口
什么时候警告?视图如何成为我们程序状态的函数
创建警告,设置显示警报的条件。
按钮与警告双向绑定
点击按钮出现警告,当警告消失时为false
5.项目
1)账单
输入费用,多少人分担费用,想给多少小费
添加三个@state属性
a .输入费用,显示费用
b.选择人数,设置导航栏
为什么默认值设置的2程序执却为4呢?
我们实际上将其设置为第三行,四个人
c.选择小费百分比,设置提示语
d.计算总值,调整精度
var totalPerPerson: Double {
let peopleCount = Double(numberOfPeople + 2)
let tipSelection = Double(tipPercentages[tipPercentage])
let orderAmount = Double(checkAmount) ?? 0
let tipValue = orderAmount / 100 * tipSelection
let grandTotal = orderAmount + tipValue
let amountPerPerson = grandTotal / peopleCount
return amountPerPerson;
}