【问题标题】:SwiftUI: Unexpectedly found nil while unwrapping an Optional valueSwiftUI:在展开可选值时意外发现 nil
【发布时间】:2021-12-30 04:44:56
【问题描述】:

我正在关注斯坦福的 CS193p 开发 iOS 应用程序在线课程。 我正在尝试使用Assignment 6 (Memorize Themes.pdf)

当我在模拟器中运行我的应用程序并在编辑模式下点击列表行以调出工作表时,我收到以下致命错误: 线程 1:致命错误:在展开可选值时意外发现 nil

问题:为什么索引匹配 themeToEdit 里面的主题数组是零?

请帮帮我。

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: {$0.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")
        }
    }
}

【问题讨论】:

  • 您是否使用调试器和/或打印语句确保在代码失败之前一切都按预期工作?
  • 当我将ThemeEditor(theme: $themeStore.themes[currentThemeIndex!]) 更改为ThemeEditor(theme: $themeStore.themes[0]) 时,没有错误。但当然,它总是显示第一个主题,而不是点击的主题。
  • 你在哪里激活编辑模式?

标签: swift swiftui combine


【解决方案1】:

您正在获取该值,因为该值可能尚未设置,因为@State 的机制会触发willSet 上的观察者,而不是didSet。要解决您的问题,您可以摆脱 isEditing 属性并完全依赖 themeToEdit 属性。

.sheet(item: $themeToEdit) { theme in
    let index = themeStore.themes.firstIndex(where: { $0.id == theme.id })
    ThemeEditor(theme: $themeStore.themes[index!])
}

更新了tapGesture 实现。

private func tapGesture(theme: Theme) -> some Gesture {
    TapGesture().onEnded { _ in
        themeToEdit = theme
    }
}

文档:sheet(item:onDismiss:content:)

【讨论】:

  • 谢谢!!!第一个版本正在运行:.sheet(item: $themeToEdit) { theme in let index = themeStore.themes.firstIndex(where: { $0.id == theme.id }) ThemeEditor(theme: $themeStore.themes[index!]) } 第二个给我错误:“无法将 'Theme' 类型的值转换为预期的参数类型 'Binding'”
  • 哦,对了,我盲目地猜到了你需要传递给ThemeEditor的参数类型。我将删除它:)
猜你喜欢
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 2020-09-19
  • 2017-01-23
  • 2021-04-10
  • 2016-10-18
  • 2017-04-09
相关资源
最近更新 更多