本文主要内容
一.Text & Label
二.Button & Link
三.Image & AsyncImage
四.TimelineView & Canvas
五.TextEditor & TextField
六.ColorPicker
七.Picker
八.ProgressView
九.Slider
十.Toggle & Stepper
一.Text & Label
1.1、Text视图
Text是显示一行或多行只读文本的视图。类似UIKit中的UILabel,是一个结构体:
@frozen struct Text
字体
通过.font方法设定Text字体。SwiftUI提供了众多的系统字体可用:
extension Font {
public static let largeTitle: Font
public static let title: Font
public static let title2: Font
public static let title3: Font
public static let headline: Font
public static let subheadline: Font
public static let body: Font
public static let callout: Font
public static let footnote: Font
public static let caption: Font
public static let caption2: Font
}
// 系统字体
Text("系统字体")
.font(.headline)
// 自定义字体
Text("自定义字体")
.font(Font.custom("PingFangSC-Regular",fixedSize: 20))
字体颜色
通过foregroundColor设定字体颜色。
Text("前景色")
.font(.subheadline)
.foregroundColor(.gray)
字重
通过fontWeight方法设定字重,系统提供的可用字重如下:
@frozen public struct Weight : Hashable {
public static let ultraLight: Font.Weight
public static let thin: Font.Weight
public static let light: Font.Weight
public static let regular: Font.Weight
public static let medium: Font.Weight
public static let semibold: Font.Weight
public static let bold: Font.Weight
public static let heavy: Font.Weight
public static let black: Font.Weight
}
Text("字重")
.font(.body)
.fontWeight(.semibold)
粗体、斜体、下划线、删除线
可以给Text设定一些特殊的样式,如粗体、斜体、下划线、删除线等。
Text("粗体")
.font(.body)
.bold()
Text("italic斜体")
.font(.body)
.italic()
Text("下划线")
.font(.body)
.underline()
Text("删除线")
.font(.body)
.strikethrough()
字距、字距调整、行间距
Text相比Label要方便得多,UILabel调整字间距或行间距需要借助AttributedString,而Text提供了对应的API。
Text("字间距")
.tracking(5.0)
.background(Color.red)
Text("字距调整")
.kerning(5.0)
.background(Color.blue)
Text("行间距/n行间距")
.lineSpacing(2)
.background(Color.green)
最大行数
通过lineLimit设定最大行数。
Text("最大2行\n最大2行\n最大2行")
.lineLimit(2)
其他设置 其他设置如内间距、基准线偏移等。
Text("内间距")
.padding(10)
.background(Color.black)
Text("基准线偏移")
.baselineOffset(10)
.background(Color.yellow)
示例
struct TextTestView: View {
@State private var textContent = "点击之前"
var body: some View {
VStack(alignment: .center, spacing: 10, content: {
// 1.字体
Text("系统字体")
.font(.headline)
Text("自定义字体")
.font(Font.custom("PingFangSC-Regular", fixedSize: 20))
.foregroundColor(.yellow)
// 2.字体颜色
Text("前景色")
.font(.subheadline)
.foregroundColor(.gray)
Text("背景色")
.font(.body)
.foregroundColor(.red)
.background(Color.green)
// 3.字重
Text("字重")
.font(.body)
.fontWeight(.semibold)
// 4.粗体
Text("粗体")
.font(.body)
.bold()
// 5.下划线
Text("下划线")
.font(.body)
.underline()
.foregroundColor(.green)
// 6.斜体
Text("italic(只支持英文)")
.font(.body)
.italic()
// 7.删除线
Text("删除线")
.font(.body)
.strikethrough()
.foregroundColor(.red)
})
VStack(alignment: .center, spacing: 10, content: {
// 1.字距、字距调整、行间距
Text("字间距")
.tracking(5.0)
.background(Color.red)
Text("字距调整")
.kerning(5.0)
.background(Color.blue)
Text("行间距/n行间距")
.lineSpacing(2)
.background(Color.green)
// 2.最大行数
Text("最大2行\n最大2行\n最大2行")
.lineLimit(2)
// 3.内间距、基准线偏移
Text("内间距")
.padding(10)
.background(Color.black)
Text("基准线偏移")
.baselineOffset(10)
.background(Color.yellow)
// 4.点击手势
Text(self.textContent)
.onTapGesture(count: 1, perform: {
self.textContent = "点击之后"
})
})
}
}
1.2、Label视图
Label视图是用户界面项的标准标签,由带有标题的图标组成。是一个结构体:
struct Label<Title, Icon> where Title : View, Icon View
- 用户界面中最常见和最容易识别的组件之一就是图标和标签的组合。如
collections、lists、menus of action items、disclosable lists等。通过提供一个标题和图像名称(如SF Symbols集合中的图标),就可以以最简单的形式创建一个标签。
// 示例:标题和图像组合的Label视图
Label("Lightning", systemImage: "bolt.fill")
预览结果
- 可以通过
labelStyle()修饰符设置标签的样式,如titleOnly表示只显示文字,iconOnly表示只显示图标,同时使用时只有第一个样式起作用。
示例:`labelStyle()`修饰符
Label("Lightning", systemImage: "bolt.fill")
.labelStyle(.titleOnly)
// .labelStyle(.iconOnly)
// .labelStyle(.titleAndIcon)
- 可以通过修改现有的样式来创建自定义的标签样式。
// 示例:给标签样式添加红色边框
Struc RedBorderedLabelStyle: LabelStyle {
func makeBody(configuration: Configuration) -> some View {
Label(configuration)
.border(Color.red)
}
}
- 编程方式创建标签,自定义标签的文字和图标。
示例:设置本地图片
Label("Rain", image: Image.init("img"))
// 示例:
Label {
Text("Hello, world!")
.font(.body)
.foregroundColor(.primary)
} icon: {
Circle()
.stroke(lineWidth: 5)
.foregroundColor(.red)
.frame(width: 34, height: 34, alignment: .center)
.overlay(Text("5"))
}
预览结果
二.Button & Link
2.1、Button
- Button视图是
启动操作的控件。结构体:
struct Button<Label> where Label : View
- 创建方式有如下
3种:
// 方式1
Button("Sign In") {
Text("Sign In")
}.foregroundColor(.blue).font(.title2)
// 方式2
Button {
print("action1")
} label: {
Text("button1")
}
// 方式3
Button(action: {
print("action2")
}){
Text("button2")
}
2.2、Link
- Link是导航到URL的控件。结构体:
struct Link<Label> where Label : View
- 创建方式有如下
2种:
// 方式1
Link(destination: URL.init(string: "www.baidu.com")!) {
Text("link")
}
// 方式2
Link("test", destination: URL.init(string: "www.baidu.com")!)
三.Image & AsyncImage
3.1、Image
- Image是显示本地图片的视图。结构体:
@frozen struct Image
- 创建方式如下:
// 方式1:加载图片(默认Assets中的图片)
Image("baby").resizable().scaledToFit()
// 方式2:加载直接拉进工程中的图片(不建议使用)
Image(uiImage:.init(named: "baby")!)
注意⚠️:此处图片默认加载Assets中的图片。如果其中没有,则无法加载图片,并且打印log“[SwiftUI] No image named 'baby' found in asset catalog for...”,
3.2、AsyncImage
- AsyncImage是显示网络图片的视图。
- 可以加载网络图片,并且可以设置一张默认的占位图。
AsyncImage(url: URL.init(string: "https://gp-dev.cdn.bcebos.com/gp-dev/upload/file/source/d642fa9e1210194ccc228947af9283c7.png")) { img in
img.resizable()
} placeholder: {
Image("baby").resozable().scaledToFit()
}.frame(width: 120, height: 120)
四.TimelineView & Canvas
4.1、TimelineView
- TimelineView根据提供的时间表进行更新的视图。结构体:
struct TimelineView<Schedule, Content> where Schedule : TimelineSchedule
按计划的更新View。创建方式有3种
// 方式1:每分钟更新
TimelineView(.everyMinute) { context in
}
// 方式2:自定义更新计划-开始时间、更新间隔(秒),类似NSTimer
// 时钟
TimelineView(.periodic(from: Date.now, by: 1.0)) { context in
Text(context.date.description).font(.largeTitle)
}
// 方式3:自定义更新计划-开始时间、更新间隔,类似NSTimer
TimelineView(.explicit(sequence)) { context in
}
4.2、Canvas
- 绘制画布。结构体:
struct Canvas<Symbols> where Symbols : View
// 示例
Canvas { context, size in
// Drawing code
context.stroke(Path(ellipseIn: CGRect(origin: .zero, size: size)), with: .color(.orange), lineWidth: 5)
}.frame(width: 100, height: 50).border(.blue, width: 3) // 画布尺寸,画布边框线条宽度
预览结果
五.TextEditor & TextField
5.1、TextEditor(相当于UITextView)
- 可以显示和编辑长文本的视图。结构体:
struct TextEditor
// 示例
// @State用于提示编译器需要刷新UI
@State var string: String = "Placeholder"
TextEditor(text: $string).frame(width: 200, height: 100)
5.2、TextField
- 可以显示和编辑长文本的视图。相当于UIKit中的UITextField,单行文本输入框。比如登录用户名、密码等。结构体:
struct TextEditor
- TextField的初始化:
@State private var inputMessage = ""
TextField("inputPlaceHolder", text: $inputMessage).textFieldStyle(.roundedBorder).font(.largeTitle).frame(width: 100, height: 50) // 一般要设置frame
.onSubmit {
// 点击键盘的return
print("点击了return")
}
六.ColorPicker
- 颜色选择器。用于从系统颜色选择器UI中选择颜色的控件。
@State private var bgColor = Color.red
ColorPicker("ColorPicker", selection: $customColor, supportsOpacity: false).font(.largeTitle).foregroundColor(bgColor)
七.Picker
- 选择器。用于从一组互斥值中进行选择的控件。
enum Person: String {
case zhangsan
case lisi
case wangwu
case zhouwu
case zhengwang
}
@State var selectionPerson = Person.wangwu
Picker(selection: $selectionPerson, label: Text("Picker")) {
Text("zhangsan").tag(Person.zhangsan)
Text("lisi").tag(Person.lisi)
Text("wangwu").tag(Person.wangwu)
Text("zhouwu").tag(Person.zhouwu)
Text("zhengwang").tag(Person.zhengwang)
}
// 同步显示选中的Person
Text("selectioned Person:\(selectionedPerson.rawValue)").foregroundColor(.blue)
.textSelection(.enabled) // 文本长按可拷贝
八.ProgressView
- 进度条,显示任务完成进度的视图。
@State var progress = 0.5
ProgressView(value: progress, total: 10, label: {
Text("SwiftUI")
}, currentValueLabel: {
Text("当前值:\(progress)")
})
.background(.blue) // 整个进度条背景
.tint(.red) // 进度颜色
Button("增加") {
progress += 0.5
}
Button("较少") {
progress -= 0.5
}
- 当value未赋值且不指定样式时,默认显示加载中的"菊花"样式。同时也可以通过设置
progressViewStyle()来改变其样式,linear为进度条,circular为正在加载。
ProgressView()
九.Slider
- 滑动进度条。一种从有界线性范围的值中选择值的控件。
@State var isSliding = false
@State var speed = 0
// 1.
// in: 滑动范围,step:步频(有in才能设置),onEditingChanged:是否在滑动
Slider(value: $speed, in: 0...100, onEditingChanged: { editing in
print(editing)
isSliding = editing
}).tint(.red)
Text("\(speed)").foregroundColor(isSliding ? .red : .gray).bold()
// 2.
Slider(value: $speed, in: 0...100) {
} minimumValueLabel: {
Text("0")
} maximumValueLabel: {
Text("\(speed)")
}
注意⚠️:任何容器中有且只能拥有不超过`10`个View
十.Toggle & Stepper
10.1 开关Toggle
- 开关。在打开和关闭状态之间切换的控件。
@State var toggleStatus = false
// tint:开启时颜色。为了不影响colorMultiply,设置opacity(0)
// colorMultiply:为颜色叠加,三原色RGB
Toggle(isOn: $toggleStatus) {
Test("Toggle")
}.tint(.blue.opacity(0)).colorMultiply(.black)
10.2 Stepper
- 步进器。一种执行递增和递减操作的控件,即可以设置步长的步进控件。
@State var value = 0
let colors: [Color] = [.orange, .red, gray, .blue, .green, .purple, .pink]
func stepperAction(isIncrement: Bool) {
value = value + isIncrement ? 1 : -1
if value >= colors.count { value = 0 }
if value < 0 { value = colors.count - 1 }
}
Stepper(value: $value, in: 0...9, step: 1) {
Text("\(value)").font(.largeTitle)
}
Stepper {
Text("value:\(value) Color:\(colors[value].description)").foregroundColor(colors[value]).font(Font.system(.title2).bold())
} onIncrement: {
stepperAction(isIncrement: true)
} onDecrement: {
stepperAction(isIncrement: false)
}