【发布时间】:2021-06-07 08:27:02
【问题描述】:
我有一个简单的演示应用程序,我在一个包含两个部分的列表中显示项目。第一部分显示最喜欢的项目,第二部分包含其余项目(不是收藏夹)。
如果我更改 isFav 状态,就会出现奇怪的行为。
在 iPhoneOS 上:
- 当我选择一个项目时,
DetailView将出现。 - 如果我更改
isFav状态(切换)DetailView将消失 - Video
在 iPadOS 上:
- 当我选择一个项目时,
DetailView将出现。 - 如果我更改
isFav状态(切换)DetailView不会消失但在侧边栏中,选择 [消失] - Video
//
// ContentView.swift
// Shared
//
// Created by Christian on 06.06.21.
//
import SwiftUI
//MARK: - Data Model
struct Item: Identifiable, Equatable, Hashable {
var id = UUID().uuidString
var isFav = false
var text: String
}
struct ItemScoped: Identifiable, Equatable, Hashable {
var id: String {
return item.id
}
var item: Item
var index: Int
}
//MARK: Store
class ItemStore: ObservableObject {
@Published var items = [Item(text: "Item 1"),
Item(text: "Item 2"),
Item(isFav: true, text: "Item 3"),
Item(text: "Item 4")]
func scopedItems(isFav: Bool) -> [ItemScoped] {
let sItems: [ItemScoped] = items.compactMap {
guard let idx = items.firstIndex(of: $0) else { return nil }
//find(items, $0)
return ItemScoped(item: $0, index: idx)
}
return sItems.filter { $0.item.isFav == isFav }
}
}
//MARK: - Views
struct ContentView: View {
// usally this is @EnvironmetObject, due to simplicity I put it here
@StateObject var store: ItemStore = ItemStore()
var body: some View {
NavigationView {
List {
Section(header: Text("Favorites")) {
ForEach(store.scopedItems(isFav: true)) { scopedItems in
NavigationLink(
destination: DetailView(item: $store.items[scopedItems.index]),
label: {
RowView(item: $store.items[scopedItems.index])
})
}
}
Section(header: Text("Other")) {
ForEach(store.scopedItems(isFav: false)) { scopedItems in
NavigationLink(
destination: DetailView(item: $store.items[scopedItems.index]),
label: {
RowView(item: $store.items[scopedItems.index])
})
}
}
}
.navigationTitle("Items")
}
}
}
// MARK: Row View
/// RowView for item, tapping the text toggle the `isFav` state
struct RowView: View {
@Binding var item: Item
var body: some View {
Label(
title: { Text(item.text) },
icon: { item.isFav ? Image(systemName: "star.fill") : Image(systemName: "star")}
)
}
}
// MARK: Detail View
/// DetailView to change item `text` and toggle `isFav` state
struct DetailView: View {
@Binding var item: Item
var body: some View {
VStack {
Spacer()
.frame(height: 20.0)
TextField("Title", text: $item.text)
.background(Color.gray.opacity(0.2))
.padding(10)
Toggle("is Fav", isOn: $item.isFav.animation())
.padding()
Spacer()
}
.padding()
}
}
// MARK: - Preview
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
【问题讨论】:
-
这种行为并不奇怪,它实际上是预期的行为,因为当
isFav状态发生变化时,List正在更新,并且最喜欢的项目正在从列表中删除。跨度> -
@cedricbahirwe 它没有被删除它只显示在另一个部分。另一个示例是,如果列表的排序基于上次输入日期,那么每次用户在“DetailView”中编辑项目时,详细视图都会消失。这是无法预料的,因为在 iPadOS 中它的行为不同。
标签: swiftui swiftui-list swiftui-navigationlink swiftui-navigationview