SwiftUI:在展开可选值时意外发现 nil
SwiftUI: Unexpectedly found nil while unwrapping an Optional value
我正在学习斯坦福 iOS 在线课程的 CS193p 开发应用程序。
我正在尝试执行 Assignment 6 (Memorize Themes.pdf).
当我 运行 我的应用程序在模拟器和编辑模式下点击列表行以显示 sheet 时,我收到以下致命错误:
线程 1:致命错误:在展开可选值时意外发现 nil
问题:为什么匹配 themeToEdit
themes数组中的索引为nil?
请帮帮我。
import SwiftUI
// Required Task 3: Your Memorize application should now show a “theme chooser” UI when it launches.
struct ThemeChooserView: View {
@EnvironmentObject var themeStore: ThemeStore
@State private var editMode: EditMode = .inactive
var body: some View {
NavigationView {
List {
ForEach(themeStore.themes) { theme in
NavigationLink(destination: EmojiMemoryGameView(game: EmojiMemoryGame(theme: theme))) {
VStack(alignment: .leading) {
Text(theme.name)
.foregroundColor(theme.color)
.font(.title)
Text(themeCardsDescription(theme: theme))
}
.gesture(editMode == .active ? tapGesture(theme: theme) : nil)
}
}
.onDelete { indexSet in
themeStore.themes.remove(atOffsets: indexSet)
}
.onMove { indexSet, newOffset in
themeStore.themes.move(fromOffsets: indexSet, toOffset: newOffset)
}
}
.sheet(isPresented: $isEditing) {
let currentThemeIndex = themeStore.themes.firstIndex(where: {[=10=].id == themeToEdit?.id})
ThemeEditor(theme: $themeStore.themes[currentThemeIndex!]) // ERROR: - Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
}
.navigationTitle("Memorize")
.toolbar {
ToolbarItemGroup(placement: .navigationBarLeading) {
plusButton
}
ToolbarItemGroup {
EditButton()
}
}
.environment(\.editMode, $editMode)
}
}
@State private var isEditing: Bool = false
@State private var themeToEdit: Theme?
private func tapGesture(theme: Theme) -> some Gesture {
TapGesture().onEnded { _ in
themeToEdit = theme
isEditing = true
}
}
private func themeCardsDescription(theme: Theme) -> String {
let numberOrAll = theme.numberOfPairsOfCards == theme.emojis.count ? "All" : "\(theme.numberOfPairsOfCards)"
return numberOrAll + " pairs from \(theme.emojis.joined(separator: ""))"
}
private var plusButton: some View {
Button {
let theme = Theme(name: "New Theme", emojis: ["", ""], numberOfPairsOfCards: 2, color: .black)
themeStore.themes.append(theme)
} label: {
Image(systemName: "plus")
}
}
}
您正在获取该值,因为该值可能尚未设置,因为 @State
的机制会触发 willSet
上的观察者,而不是 didSet
。要解决您的问题,您可以摆脱 isEditing
属性 并完全依赖 themeToEdit
属性.
.sheet(item: $themeToEdit) { theme in
let index = themeStore.themes.firstIndex(where: { [=10=].id == theme.id })
ThemeEditor(theme: $themeStore.themes[index!])
}
更新了 tapGesture
实施。
private func tapGesture(theme: Theme) -> some Gesture {
TapGesture().onEnded { _ in
themeToEdit = theme
}
}
我正在学习斯坦福 iOS 在线课程的 CS193p 开发应用程序。 我正在尝试执行 Assignment 6 (Memorize Themes.pdf).
当我 运行 我的应用程序在模拟器和编辑模式下点击列表行以显示 sheet 时,我收到以下致命错误: 线程 1:致命错误:在展开可选值时意外发现 nil
问题:为什么匹配 themeToEdit
themes数组中的索引为nil?
请帮帮我。
import SwiftUI
// Required Task 3: Your Memorize application should now show a “theme chooser” UI when it launches.
struct ThemeChooserView: View {
@EnvironmentObject var themeStore: ThemeStore
@State private var editMode: EditMode = .inactive
var body: some View {
NavigationView {
List {
ForEach(themeStore.themes) { theme in
NavigationLink(destination: EmojiMemoryGameView(game: EmojiMemoryGame(theme: theme))) {
VStack(alignment: .leading) {
Text(theme.name)
.foregroundColor(theme.color)
.font(.title)
Text(themeCardsDescription(theme: theme))
}
.gesture(editMode == .active ? tapGesture(theme: theme) : nil)
}
}
.onDelete { indexSet in
themeStore.themes.remove(atOffsets: indexSet)
}
.onMove { indexSet, newOffset in
themeStore.themes.move(fromOffsets: indexSet, toOffset: newOffset)
}
}
.sheet(isPresented: $isEditing) {
let currentThemeIndex = themeStore.themes.firstIndex(where: {[=10=].id == themeToEdit?.id})
ThemeEditor(theme: $themeStore.themes[currentThemeIndex!]) // ERROR: - Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
}
.navigationTitle("Memorize")
.toolbar {
ToolbarItemGroup(placement: .navigationBarLeading) {
plusButton
}
ToolbarItemGroup {
EditButton()
}
}
.environment(\.editMode, $editMode)
}
}
@State private var isEditing: Bool = false
@State private var themeToEdit: Theme?
private func tapGesture(theme: Theme) -> some Gesture {
TapGesture().onEnded { _ in
themeToEdit = theme
isEditing = true
}
}
private func themeCardsDescription(theme: Theme) -> String {
let numberOrAll = theme.numberOfPairsOfCards == theme.emojis.count ? "All" : "\(theme.numberOfPairsOfCards)"
return numberOrAll + " pairs from \(theme.emojis.joined(separator: ""))"
}
private var plusButton: some View {
Button {
let theme = Theme(name: "New Theme", emojis: ["", ""], numberOfPairsOfCards: 2, color: .black)
themeStore.themes.append(theme)
} label: {
Image(systemName: "plus")
}
}
}
您正在获取该值,因为该值可能尚未设置,因为 @State
的机制会触发 willSet
上的观察者,而不是 didSet
。要解决您的问题,您可以摆脱 isEditing
属性 并完全依赖 themeToEdit
属性.
.sheet(item: $themeToEdit) { theme in
let index = themeStore.themes.firstIndex(where: { [=10=].id == theme.id })
ThemeEditor(theme: $themeStore.themes[index!])
}
更新了 tapGesture
实施。
private func tapGesture(theme: Theme) -> some Gesture {
TapGesture().onEnded { _ in
themeToEdit = theme
}
}