由于 API 变动,此文章部分内容已失效,最新完整中文教程及代码请查看 https://github.com/WillieWangWei/SwiftUI-Tutorials
微信技术群
SwiftUI
代表未来构建 App 的方向,欢迎加群一起交流技术,解决问题。
加群现在需要申请了,可以先加我微信,备注 “SwiftUI”,我会拉你进群。
处理用户输入
在
Landmarks
app 中,用户可以标记他们喜欢的地点,并在列表中过滤出来。要实现这个功能,我们要先在列表中添加一个开关,这样用户可以只看到他们收藏的内容。另外还会添加一个星形按钮,用户可以点击该按钮来收藏地标。下载起始项目文件并按照以下步骤操作,也可以打开已完成的项目自行浏览代码。
- 预计完成时间:20 分钟
- 初始项目文件:下载
1. 标记用户收藏的地标
首先,通过优化列表来清晰地给用户显示他们的收藏。给每个被收藏地标的 LandmarkRow
添加一颗星。
1.1 打开起始项目,在 Project navigator
中选择 LandmarkRow.swift
。
1.2 在 spacer
的下面添加一个 if
语句,在其中添加一个星形图片来测试当前地标是否被收藏。
在 SwiftUI
block 中,我们使用 if
语句来有条件的引入 view 。
LandmarkRow.swift
import SwiftUI
struct LandmarkRow: View {
var landmark: Landmark
var body: some View {
HStack {
landmark.image(forSize: 50)
Text(landmark.name)
Spacer()
if landmark.isFavorite {
Image(systemName: "star.fill")
.imageScale(.medium)
}
}
}
}
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
Group {
LandmarkRow(landmark: landmarkData[0])
LandmarkRow(landmark: landmarkData[1])
}
.previewLayout(.fixed(width: 300, height: 70))
}
}
1.3 由于系统图片是基于矢量的,所以我们可以通过 foregroundColor(_:)
方法来修改它们的颜色。
当 landmark
的 isFavorite
属性为 true
时,星星就会显示。稍后我们会在教程中看到如何修改这个属性。
LandmarkRow.swift
import SwiftUI
struct LandmarkRow: View {
var landmark: Landmark
var body: some View {
HStack {
landmark.image(forSize: 50)
Text(landmark.name)
Spacer()
if landmark.isFavorite {
Image(systemName: "star.fill")
.imageScale(.medium)
.foregroundColor(.yellow)
}
}
}
}
struct LandmarkRow_Previews: PreviewProvider {
static var previews: some View {
Group {
LandmarkRow(landmark: landmarkData[0])
LandmarkRow(landmark: landmarkData[1])
}
.previewLayout(.fixed(width: 300, height: 70))
}
}
2. 过滤 List View
我们可以自定义 list view 让它显示所有的地标,也可以只显示用户收藏的。为此,我们需要给 LandmarkList
类型添加一点 state
。
state
是一个值或一组值,它可以随时间变化,并且会影响视图的行为、内容或布局。我们用具有 @State
特征的属性将 state
添加到 view 中。
2.1 在 Project navigator
中选择 LandmarkList.swift
,添加一个名叫 showFavoritesOnly
的 @State
属性,把它的初始值设为 false
。
LandmarkList.swift
import SwiftUI
struct LandmarkList: View {
@State var showFavoritesOnly = false
var body: some View {
NavigationView {
List(landmarkData)