SwiftUI .sheet 解包可选值时意外发现 nil

san*_*.gs 5 swiftui

问题

下面的例子比我能解释的更好地突出了我的问题。在呈现表格之前,我明确地为可选变量赋予一个值。该表需要一个非可选变量来初始化,它不注册该值并表示它为零。我不明白为什么如果我只在给可选值赋予值后调用工作表,就会出现这种情况。任何帮助将不胜感激。谢谢!

我尝试过的

在我替换的示例中:

.sheet(isPresented: $showModalView, content: {
     EditBookView(book: editingBook!) //Fatal error here
})
Run Code Online (Sandbox Code Playgroud)

和:

.sheet(isPresented: $showModalView, content: {
     if let book = editingBook {
         EditBookView(book: book)
     }
})
Run Code Online (Sandbox Code Playgroud)

但是,这仅显示一张空表(意味着它editingBook是空的)。但是,有趣的是,当我关闭这个空工作表并选择列表中的另一个项目时,视图会按预期显示。

可重现的例子

import SwiftUI

struct Book: Identifiable {
    var id: UUID
    var title: String
    
    init(title: String){
        self.title = title
        self.id = UUID()
    }
}

struct ContentView: View {
    
    @State var books = [Book]()
    @State var showModalView = false
    
    @State var editingBook: Book? = nil
    
    var body: some View {
        List{
            ForEach(books){ book in
                VStack(alignment: .leading){
                    Text(book.title)
                            .font(Font.title.bold())
                    Text("id: \(book.id.uuidString)")
                        .foregroundColor(.gray)
                    Button(action: {
                        editingBook = book
                        showModalView = true
                    }){
                        Text("Edit")
                            .foregroundColor(.accentColor)
                    }
                    .buttonStyle(PlainButtonStyle())
                    .padding(.top)
                }
            }
        }
        .padding()
        .onAppear{
            for i in 0...50 {
                books.append(Book(title: "Book #\(i)"))
            }
        }
        .sheet(isPresented: $showModalView, content: {
            EditBookView(book: editingBook!) //Fatal error here
        })
    }
    
}

struct EditBookView: View {
    var book: Book
    
    var body: some View {
        Text(book.title)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

enum SheetChoice: Hashable, Identifiable {
    case addContentView
    case editContentView

    var id: SheetChoice { self }
}

...


.sheet(item: $sheetChoice){ item in
                        switch item {
                        case .addContentView:
                            AddContentView()
                                .environmentObject(model)
                        case .editContentView:
                            //if let selectedContent = selectedContent {
                                ContentEditorView(book: selectedContent!, editingFromDetailView: false)
                                    .environmentObject(model)
                            //}
                        }
}

Run Code Online (Sandbox Code Playgroud)

msm*_*lko 4

确保您还在editingBook主体内部使用(不仅仅是工作表构建块)。\nSwiftUI 跟踪在其主体中使用了哪些状态变量。当不使用 it\xe2\x80\x99s 时,当调用你的主体并忽略对该状态变量的更改时,你可能会遇到这种奇怪的情况。

\n

所以基本上在你的正文的开头添加这一行:

\n
var body: some View {\n   _ = editingBook\n   \n   return <your view>\n}\n
Run Code Online (Sandbox Code Playgroud)\n

或者,您可以使用此 .sheet 修饰符版本:\n https://developer.apple.com/documentation/swiftui/view/sheet(item:ondismiss:content:)

\n