我们在浏览商品列表的时候需要搜索自己需要的商品,我们也可以建立一个收藏架保存我们需要的商品,我们需要在喜欢的商品row加星标注。
我们需要在Commodity
中增加一个字段来判断是否收藏该商品
/// 是否收藏
var isFavorite: Bool
复制代码
我们需要在CommodityRow
这个类中增加一个控件来区分是否收藏
Image(commodity.isFavorite ? "shoucang1":"shoucang")
.padding(.trailing)
复制代码
过滤列表视图您可以自定义列表视图,使其显示所有地标,或仅显示用户的最爱。 为此,您需要向 CommodityView
类型添加一些状态。状态是一个值或一组值,可以随时间变化,并影响视图的行为、内容或布局。 您可以使用带有 @State
属性的属性向视图添加状态。
struct CommodityView:View {
@State private var showFavoritesOnly = true
var filteredCommity:[Commodity] {
Commoditys.filter { commodity in
(!showFavoritesOnly || commodity.isFavorite)
}
}
var body: some View {
NavigationView {
List(filteredCommity, id: \.id) { commodity in
NavigationLink(destination: CommodityViewDetail(commodity: commodity)){
CommodityRow(commodity: commodity)
}
}
.navigationTitle("商品列表")
}
}
}
复制代码
我们可以在界面上添加一个切换状态的按钮,我们可以切换状态来查看收藏功能
struct CommodityView:View {
@State private var showFavoritesOnly = true
var filteredCommity:[Commodity] {
Commoditys.filter { commodity in
(!showFavoritesOnly || commodity.isFavorite)
}
}
var body: some View {
NavigationView {
List {
Toggle(isOn: $showFavoritesOnly) {
Text("是否只查看收藏")
}
ForEach(filteredCommity, id: \.id) { commodity in
NavigationLink(destination: CommodityViewDetail(commodity: commodity)){
CommodityRow(commodity: commodity)
}
}
}
.navigationTitle("商品列表")
}
}
}
复制代码
使用 Observable
对象进行存储,为了让用户准备控制哪些特定地标是最喜欢的,您首先将地标数据存储在一个可观察对象中。可观察对象是数据的自定义对象,可以绑定到 SwiftUI
环境中存储的视图。 SwiftUI
会监视可能影响视图的可观察对象的任何更改,并在更改后显示视图的正确版本。
可观察对象需要发布对其数据的任何更改,以便其订阅者可以获取更改。用@Published
修饰
final class ModelData: ObservableObject {
/// 商品数组
@Published var Commoditys:[Commodity] = load("Commoditys.json")
}
复制代码
在 CommodityView.swift
中,向视图添加 @EnvironmentObject
属性声明, HStack {
Text(landmark.name)
.font(.title)
.foregroundColor(.primary)
FavoriteButton(isSet: $modelData.landmarks[landmarkIndex].isFavorite)
}向预览添加environmentObject(_:)
修饰符。只要 environmentObject(_:)
修饰符已应用于父级,modelData
属性就会自动获取其值。
struct CommodityView:View {
@State private var showFavoritesOnly = false
@EnvironmentObject var modelData: ModelData
var filteredCommity:[Commodity] {
modelData.Commoditys.filter { commodity in
(!showFavoritesOnly || commodity.isFavorite)
}
}
var body: some View {
NavigationView {
List {
Toggle(isOn: $showFavoritesOnly) {
Text("是否只查看收藏")
}
ForEach(filteredCommity, id: \.id) { commodity in
NavigationLink(destination: CommodityViewDetail(commodity: commodity)){
CommodityRow(commodity: commodity)
}
}
}
.navigationTitle("商品列表")
}
}
}
struct CommodityView_Previews: PreviewProvider {
static var previews: some View {
ForEach(["iPhone SE (2nd generation)", "iPhone XS Max"], id: \.self) { deviceName in
CommodityView()
.previewDevice(PreviewDevice(rawValue: deviceName))
.previewDisplayName(deviceName)
.environmentObject(ModelData())
}
}
}
复制代码
更新 SwiftUIDemoApp
以创建模型实例并使用 environmentObject(_:)
修饰符将其提供ContentView。
在应用程序的生命周期内,使用@StateObject
属性只为给定属性初始化一次模型对象。 当您在应用程序实例中使用该属性时(如此处所示)以及在视图中使用它时,情况都是如此。
struct SwiftUIDemoApp: App {
@StateObject private var modelData = ModelData()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(modelData)
}
}
}
复制代码