やりたいこと
- NavigationBarItemとFloating action buttonでそれぞれシートをpresentする
とりあえず実装してみた
Boolの@Stateを2つsheet modifierを2つ並べとけばええやろ
struct SomeView: View {
@State private var isScheduling: Bool
@State private var isSharing: Bool
var body: some View {
VStack(alignment: .leading) {
// ...
// fab
HStack {
Spacer()
Button {
isScheduling.toggle()
} label: {
Image(systemName: "plus")
.foregroundColor(.white)
.font(.title2)
.shadow(radius: 3)
}
.frame(width: 60, height: 60)
.background(Color.primary)
.cornerRadius(30.0)
.shadow(color: .gray, radius: 3, x: 0, y: 0)
.padding(.bottom, 16)
}
}
.navigationBarItems(trailing: Button {
isSharing.toggle()
} label: {
Image(systemName: "person.badge.plus")
})
.sheet(isPresented: $isScheduling) {
ScheduleView()
}
.sheet(isPresented: $isSharing) {
ShareView()
}
}
}
問題点
- これだと後から宣言されたmodifier(ここではshareの方)だけが生きて、先に宣言した方は死ぬ
- どうやらViewはひとつの
sheetmodifierしか持つことができないらしい
改善
struct SomeView: View {
private enum ActiveSheet: Identifiable {
case schedule
case share
var id: Int {
hashValue
}
}
@State private var activeSheet: ActiveSheet?
var body: some View {
VStack(alignment: .leading) {
// ...
// fab
HStack {
Spacer()
Button {
activeSheet = .schedule
} label: {
Image(systemName: "plus")
.foregroundColor(.white)
.font(.title2)
.shadow(radius: 3)
}
.frame(width: 60, height: 60)
.background(Color.primary)
.cornerRadius(30.0)
.shadow(color: .gray, radius: 3, x: 0, y: 0)
.padding(.bottom, 16)
}
}
.navigationBarItems(trailing: Button {
activeSheet = .share
} label: {
Image(systemName: "person.badge.plus")
})
.sheet(item: $activeSheet) { item in
switch item {
case .schedule:
ScheduleView()
case .share:
ShareView()
}
}
}
}
これで2つのsheetがpresentできるようになる
あとすっきりした
2021/5/9 追記
一つの子Viewに対しては1つ以上のsheetやfullScreenCoverは持てないが、別のViewに持たせてしまえばいくらでも追加できた
参考