問題描述

只要在同一個 View 當中有 連續 或是 嵌套 的 Sheet

有作用的 Sheet 只會是最後或最外層的一個,其他的將會不顯示

版本

Life Cycle: SwiftUI App
iOS Version: 14.0 ~ 14.4

示範

案例1(嵌套)

import SwiftUI

struct ContentView: View {
    @State private var flagInside = false
    @State private var flagOutside = false
    
    var body: some View {
        VStack {
            Button("Open inside") {
                flagInside.toggle()
            }.sheet(isPresented: $flagInside) {
                Text("inside")
            }
            
            Button("Open outside") {
                flagOutside.toggle()
            }
            
        }.sheet(isPresented: $flagOutside) {
            Text("outside")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

在這個範例中,我們創建了兩個開關,分別用來控制兩個 Sheet

在 14.5 以下的版本中,Open inside 按鈕按下去,內層的 Sheet 並不會顯示(無錯誤訊息)

但是 Open outside 按鈕按下去,外層的 Sheet 正常顯示

如果這時候把外層的 Sheet 移除,內層的 Sheet 就可以顯示了

案例2(連續)

import SwiftUI

struct ContentView: View {
    @State private var flagFirst = false
    @State private var flagSecond = false
    
    var body: some View {
        VStack {
            Button("Open first") {
                flagFirst.toggle()
            }
            
            Button("Open second") {
                flagSecond.toggle()
            }
        }.sheet(isPresented: $flagFirst) {
            Text("first")
        }.sheet(isPresented: $flagSecond) {
            Text("second")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

與上一個案例不同的地方在於把兩個 Sheet 綁在同一個 View 上

這次起作用的 Sheet 會變成最後一個,Open first 按鈕等同無效

解決方法

將 Sheet 綁到同級但不同 View 上

import SwiftUI

struct ContentView: View {
    @State private var flagFirst = false
    @State private var flagSecond = false
    
    var body: some View {
        VStack {
            Button("Open first") {
                flagFirst.toggle()
            }.sheet(isPresented: $flagFirst) {
                Text("first")
            }
            
            Button("Open second") {
                flagSecond.toggle()
            }.sheet(isPresented: $flagSecond) {
                Text("second")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

這樣就可以讓兩個 Sheet 都運作正常