このContentViewには2つの異なるモーダルビューがあるので、両方にsheet(isPresented:)
を使用していますが、最後の1つしか表示されないようです。この問題を解決するにはどうすればよいですか?または、SwiftUIのビューで複数のシートを使用することはできませんか?
struct ContentView: View {
@State private var firstIsPresented = false
@State private var secondIsPresented = false
var body: some View {
NavigationView {
VStack(spacing: 20) {
Button("First modal view") {
self.firstIsPresented.toggle()
}
Button ("Second modal view") {
self.secondIsPresented.toggle()
}
}
.navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
.sheet(isPresented: $firstIsPresented) {
Text("First modal view")
}
.sheet(isPresented: $secondIsPresented) {
Text("Only the second modal view works!")
}
}
}
}
上記のコードは警告なしにコンパイルされます(Xcode 11.2.1)。
以下のコードを試してください
enum ActiveSheet {
case first, second
}
struct ContentView: View {
@State private var showSheet = false
@State private var activeSheet: ActiveSheet = .first
var body: some View {
NavigationView {
VStack(spacing: 20) {
Button("First modal view") {
self.showSheet = true
self.activeSheet = .first
}
Button ("Second modal view") {
self.showSheet = true
self.activeSheet = .second
}
}
.navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
.sheet(isPresented: $showSheet) {
if self.activeSheet == .first {
Text("First modal view")
}
else {
Text("Only the second modal view works!")
}
}
}
}
}
次の方法で解決できる場合があります(Xcode 11.2でテスト済み)
var body: some View {
NavigationView {
VStack(spacing: 20) {
Button("First modal view") {
self.firstIsPresented.toggle()
}
.sheet(isPresented: $firstIsPresented) {
Text("First modal view")
}
Button ("Second modal view") {
self.secondIsPresented.toggle()
}
.sheet(isPresented: $secondIsPresented) {
Text("Only the second modal view works!")
}
}
.navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
}
}
ビューの背景に配置されたEmptyViewにシートを追加することもできます。これは複数回行うことができます:
.background(EmptyView()
.sheet(isPresented: isPresented, content: content))
これは、ボタンと.sheet呼び出しをグループ化するだけで実現できます。あなたが1つの先行と1つの後続がある場合、それはとても簡単です。ただし、先頭または末尾に複数のnavigationbaritemsがある場合は、それらをHStackでラップし、各ボタンをシート呼び出しでVStackでラップする必要があります。
次に、2つの末尾ボタンの例を示します。
trailing:
HStack {
VStack {
Button(
action: {
self.showOne.toggle()
}
) {
Image(systemName: "camera")
}
.sheet(isPresented: self.$showOne) {
OneView().environment(\.managedObjectContext, self.managedObjectContext)
}
}//showOne vstack
VStack {
Button(
action: {
self.showTwo.toggle()
}
) {
Image(systemName: "film")
}
.sheet(isPresented: self.$showTwo) {
TwoView().environment(\.managedObjectContext, self.managedObjectContext)
}
}//show two vstack
}//nav bar button hstack
Rohit Makwanaの回答 に加えて、コンパイラーが巨大なView
の型チェックに苦労していたため、シートの内容を関数に抽出する方法を見つけました。
extension YourView {
enum Sheet {
case a, b
}
@ViewBuilder func sheetContent() -> some View {
if activeSheet == .a {
A()
} else if activeSheet == .b {
B()
}
}
}
次のように使用できます。
.sheet(isPresented: $isSheetPresented, content: sheetContent)
これにより、コードがよりクリーンになり、コンパイラのストレスも軽減されます。