You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI 关闭最后一个sheet时如何同时dismiss多层sheet回到初始调用视图

解决多层sheet连续关闭直接回到根视图的问题

实现思路

SwiftUI中每张sheet的presentationMode仅能控制当前层级sheet的关闭,因此你在PickDefinition中调用dismiss()只能关闭当前页,上层的AddWord sheet仍会保留。
要实现直接回到BookView,只需将BookView中控制第一个sheet显隐的addingWord状态以Binding的形式逐层传递到最底层的PickDefinition,将其置为false即可一次性关闭所有层级的sheet,直接回到根视图。

具体修改步骤

  1. 给AddWord结构体新增showAddWord绑定属性,同时在BookView弹出AddWord时传入$addingWord
  2. 给PickDefinition结构体新增showAddWord绑定属性,同时在AddWord弹出PickDefinition时传入该绑定值
  3. 替换PickDefinition中选中释义后的关闭逻辑,直接将showAddWord置为false即可

修改后完整代码

struct BookView: View {
    @ObservedObject var book: Book
    @State var addingWord = false
    @Environment(\.presentationMode) var presentationMode
    var body: some View {
        VStack {
            List(Array(zip(book.words, book.definitions)), id: \.self.0) { (word, definition) in
                Text("\(word) - \(definition)")
            }
        }
        .onAppear(perform: {
            DB_Manager().openBook(name: book.name, book: self.book)
        })
        .navigationBarTitle("\(book.name)")
        .navigationBarItems(trailing: Button(action: {
            self.addingWord = true
        }) {
            Image(systemName: "plus")
        }
        ).sheet(isPresented: $addingWord) {
            // 传入binding值
            AddWord(book: self.book, showAddWord: $addingWord)
        }
    }
}

struct AddWord: View {
    @ObservedObject var book: Book
    @StateObject var currentArray = SaveArray()
    @State var addingDefinition = false
    @State var word = ""
    @State var definition = ""
    @State var allDefinitions: [String] = []
    // 新增绑定属性
    @Binding var showAddWord: Bool
    @Environment(\.presentationMode) var presentationMode
    var body: some View {
        NavigationView {
            Form {
                TextField("Word: ", text: $word)
            }
            .navigationBarTitle("Add word")
            .navigationBarItems(trailing: Button("Add") {
                if self.word != "" {
                    book.words.append(self.word)
                    getDef(self.word, book, currentArray)
                    addingDefinition = true
                }
            }).sheet(isPresented: $addingDefinition) {
                // 向下传递binding值
                PickDefinition(definitions: currentArray, book: book, word: self.word, showAddWord: $showAddWord)
            }
        }
    }
}

struct PickDefinition: View {
    @ObservedObject var definitions: SaveArray
    var book: Book
    var word: String
    // 新增绑定属性
    @Binding var showAddWord: Bool
    @Environment(\.presentationMode) var presentationMode
    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(0 ..< definitions.currentArray.count, id: \.self) { index in
                        Button("\(self.definitions.currentArray[index])", action: {
                            print("hello")
                            DB_Manager().addWords(name: self.book.name, word: self.word, definition: self.definitions.currentArray[index])
                            book.definitions.append(self.definitions.currentArray[index])
                            // 直接关闭所有层级sheet
                            self.showAddWord = false
                        })
                    }
                }
            }
            .navigationTitle("Choose")
        }
    }
}

补充说明

如果你的项目最低支持iOS 15及以上版本,也可以使用@Environment(\.dismiss)替代presentationMode,逻辑和上述方案一致,只需将绑定的状态值传到最底层直接置false即可。

内容的提问来源于stack exchange,提问作者Nikolas Caceres

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 17:48:01