SwiftUI использует ForEach и onTapGesture для обновления выбранного элемента, вызывающего сбой
У меня есть некоторый код, который я использую, идея состоит в том, что пользователь выбирает карту, которая ему нравится, и отображается лист, чтобы показать больше информации об этой карте. Проблема в том, что если у меня нет
Text(selectedCard?.name ?? "Not selected")
линия, он падает. Мне просто интересно, что я не понимаю в Swift/SwiftUI, из-за которого это происходит, и как я могу это исправить (поскольку я не хочу, чтобы он говорил, какую карту они выбрали).
Именно там, где появляется лист, он разбивается, когда находит
nil
значение для но
selectedCard
не должен быть равен нулю, когда это выполняется. Если я добавлю, казалось бы, несвязанную строку, чтобы показать, какая карта была выбрана, значение будет установлено нормально, и это не приведет к сбою.
Полный код:
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() {
...
}
}
1 ответ
Ваша проблема, вероятно, связана с тем, что алгоритм сравнения представлений имеет другой результат, если у вас есть текстовое значение, поскольку это будет различием в корневом представлении. Поскольку у вас есть две части состояния, представляющие лист, и вы принудительно разворачиваете одну из них, вы подвергаете себя опасности.
Вы должны избавиться от
.sheet(item: $selectedCard) { SpecificCardView(card: $0) }
Это также сбросит выбранную карту на ноль, когда лист будет закрыт.