I've encountered an issue that I was not able to tinker to my full satisfaction.
I have a MasterView
that changes environmentObject SelectionObject
to show ZStack content* from Link
enum. The issue is that the removal transition is almost invisible when there is a background in MasterView
(Color.gray
, when I set opacity, the animation is visible a little bit but unless it gets to low number, the overall opacity of FirstView
or SecondView
is detrimented. It works as expected without any background in MasterView
Here is my code:
class SelectionObject: ObservableObject {
@Published var selection: Link? = nil
}
struct MasterView: View {
@EnvironmentObject var selection: SelectionObject
var body: some View {
ZStack {
Color.gray
VStack {
ForEach(Link.allCases) { menu in
Button(action: {
selection.selection = menu
}, label: {
Label(menu.title, systemImage: menu.image).padding()
}
)
.tag(menu)
}
}
ForEach(Link.allCases) { menu in
if menu == selection.selection {
menu.contentView
.transition(AnyTransition.slide)
.animation(.spring())
}
}
}
}
}
struct Menu_Previews: PreviewProvider {
static var previews: some View {
MasterView().environmentObject(SelectionObject())
}
}
struct FirstView: View {
@EnvironmentObject var selection: SelectionObject
var body: some View {
ZStack {
Color.orange
VStack {
Text("First View content")
Button(action: {
selection.selection = nil
}, label: {
Text("Get back with a nice animation").padding().foregroundColor(.white)
}
)
}
}
}
}
struct SecondView: View {
@EnvironmentObject var selection: SelectionObject
var body: some View {
ZStack {
Color.orange
VStack {
Text("Second View content")
Button(action: {
selection.selection = nil
}, label: {
Text("Get back with a nice animation")
}
)
}
}
}
}
enum Link: Int, CaseIterable, Identifiable {
var id: Int {
return self.rawValue
}
case first
case second
var title: LocalizedStringKey {
switch self {
case .first: return "First"
case .second: return "Second"
}
}
var image: String {
switch self {
case .first: return "icloud"
case .second: return "display"
}
}
var contentView: AnyView {
switch self {
case .first: return AnyView ( FirstView() )
case .second: return AnyView ( SecondView() )
}
}
}
I've tried to use a zIndex way (mentioned here: Transition animation not working in SwiftUI ) but was unable to make it work as it worked only once and did not show the content on second click.
Can you help me find a way around the issue?
- I use this because I can't use
NavigationView
as myMasterView
is used in overlay in a different NavigationView and there is a frame, offset, and cornerRadius issue that prevents to click on anything unless I delete either the offset or cornerRadius.