I have 3 views that are completely separate. I furthermore, do not want the ultraThinMaterial to add on as views stack over each other.
When View 2 appears over view 1 from the bottom edge, it should get removed from the bottom edge as well.
When I tried, either only a simple opacity animation runs or the view behind gets transitioned through the bottom edge as well..
Basically aiming for ZStack of views like how the iOS default navigation works or how the sheet in Apple Maps get overlaid on top of each other.
enum ViewToShow: Identifiable {
var id: ViewToShow {
return self
}
case view1
case view2
case view3
}
@Observable
class SheetStackModel {
var viewsItemManagedByThisSheet: [ViewToShow] = []
init() {
pushIntoStack(view: .view1)
}
func getLastView() -> ViewToShow? {
return viewsItemManagedByThisSheet.last
}
func pushIntoStack(view: ViewToShow) {
withAnimation(.default.speed(1.8)) {
viewsItemManagedByThisSheet.append(view)
}
}
func popOutOfStack() {
withAnimation(.default.speed(1.8)) {
_ = viewsItemManagedByThisSheet.removeLast()
}
}
}
struct View1: View {
@Environment(SheetStackModel.self) var sheetStackModel
var body: some View {
GeometryReader { localGeo in
VStack {
Text("View 1")
Button(action: {
sheetStackModel.pushIntoStack(view: .view2)
}, label: {
Text("Go to View 2")
})
}
}
}
}
struct View2: View {
@Environment(SheetStackModel.self) var sheetStackModel
var body: some View {
GeometryReader { localGeo in
VStack {
Text("View 2")
Button(action: {
sheetStackModel.popOutOfStack()
}, label: {
Text("Go back to View 1")
})
Button("Go to Detail 3") {
sheetStackModel.pushIntoStack(view: .view3)
}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.ultraThinMaterial)
}
}
struct DetailView3: View {
@Environment(SheetStackModel.self) var sheetStackModel
var body: some View {
VStack {
Text("Even more detail View")
Button("go back to view 2") {
sheetStackModel.popOutOfStack()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.ultraThinMaterial)
}
}
struct ContentView: View {
var body: some View {
ZStack {
if let lastView = sheetStackModel.getLastView() {
switch lastView {
case .view1:
View1()
case .view2:
View2()
case .view3:
DetailView3()
}
}
}
.transition(.asymmetric(insertion: .move(edge: .bottom), removal: .move(edge: .bottom)))
}
}