SwiftUI 使用 ForEach 和 onTapGesture 来更新导致崩溃的选定元素
SwiftUI using ForEach and onTapGesture to update selected element causing crash
我有一些正在使用的代码,其想法是用户选择他们喜欢的卡片,然后出现 sheet 以显示有关该卡片的更多信息。问题是,如果我没有 Text(selectedCard?.name ?? "Not selected")
行,它就会崩溃。我只是想知道我不明白 Swift/SwiftUI 是什么导致了这种情况发生以及我该如何解决它(因为我不希望它说出他们选择了哪张卡片)。
这是 sheet 出现的地方,它在找到 selectedCard
的 nil
值时崩溃,但 selectedCard
在运行时不应该为 nil .如果我添加看似无关的行来显示选择了哪张卡,则该值设置正常并且不会崩溃。
完整代码:
import SwiftUI
struct CardsView: View {
@State private var cardlist = [Cards]()
@State private var showingSheet = false
@State private var selectedCard: Cards?
let columns = [
GridItem(.adaptive(minimum: 120))
]
var body: some View {
NavigationView() {
ScrollView (.vertical, showsIndicators: false) {
Text("View our full collection of cards below:")
.padding(.leading, 20)
.frame(maxWidth: .infinity, alignment: .leading)
Text(selectedCard?.name ?? "Not selected") // This line stops it from crashing
LazyVGrid(columns: columns, spacing: 10) {
ForEach(cardlist, id: \.name) { thecard in
CardItem(card: thecard)
.onTapGesture {
selectedCard = thecard
showingSheet.toggle()
}
}
}
.padding([.leading, .trailing])
Spacer()
}
.navigationTitle("Cards")
}
.sheet(isPresented: $showingSheet) {
SpecificCardView(card: selectedCard!)
}
.onAppear() {
loadCards()
}
}
func loadCards() {
...
}
}
您的问题可能是由于存在文本值时视图差异算法会产生不同的结果,因为这在根视图中会有所不同。由于您有两个代表 sheet 的状态,并且您正在强行解开其中一个,因此您会让自己面临危险。
您应该去掉 showingSheet
,然后改用 sheet 的项目绑定。使Cards
符合Identifiable
,然后将sheet修饰符重写为:
.sheet(item: $selectedCard) { SpecificCardView(card: [=10=]) }
当 sheet 被关闭时,这也会将您选择的卡片重置为零。
我有一些正在使用的代码,其想法是用户选择他们喜欢的卡片,然后出现 sheet 以显示有关该卡片的更多信息。问题是,如果我没有 Text(selectedCard?.name ?? "Not selected")
行,它就会崩溃。我只是想知道我不明白 Swift/SwiftUI 是什么导致了这种情况发生以及我该如何解决它(因为我不希望它说出他们选择了哪张卡片)。
这是 sheet 出现的地方,它在找到 selectedCard
的 nil
值时崩溃,但 selectedCard
在运行时不应该为 nil .如果我添加看似无关的行来显示选择了哪张卡,则该值设置正常并且不会崩溃。
完整代码:
import SwiftUI
struct CardsView: View {
@State private var cardlist = [Cards]()
@State private var showingSheet = false
@State private var selectedCard: Cards?
let columns = [
GridItem(.adaptive(minimum: 120))
]
var body: some View {
NavigationView() {
ScrollView (.vertical, showsIndicators: false) {
Text("View our full collection of cards below:")
.padding(.leading, 20)
.frame(maxWidth: .infinity, alignment: .leading)
Text(selectedCard?.name ?? "Not selected") // This line stops it from crashing
LazyVGrid(columns: columns, spacing: 10) {
ForEach(cardlist, id: \.name) { thecard in
CardItem(card: thecard)
.onTapGesture {
selectedCard = thecard
showingSheet.toggle()
}
}
}
.padding([.leading, .trailing])
Spacer()
}
.navigationTitle("Cards")
}
.sheet(isPresented: $showingSheet) {
SpecificCardView(card: selectedCard!)
}
.onAppear() {
loadCards()
}
}
func loadCards() {
...
}
}
您的问题可能是由于存在文本值时视图差异算法会产生不同的结果,因为这在根视图中会有所不同。由于您有两个代表 sheet 的状态,并且您正在强行解开其中一个,因此您会让自己面临危险。
您应该去掉 showingSheet
,然后改用 sheet 的项目绑定。使Cards
符合Identifiable
,然后将sheet修饰符重写为:
.sheet(item: $selectedCard) { SpecificCardView(card: [=10=]) }
当 sheet 被关闭时,这也会将您选择的卡片重置为零。