Problem:
I've got 3 separate views I'm displaying all at once but I only want one view showing at a time so the user can just toggle between the three views. Here is what is happening now.
The code is long below but if you copy and paste the code into Xcode you can see what is happening now. I have three views that have different size frames. You can click each view button and it will open that view.
import SwiftUI
struct ContentView: View {
@State var show1 = false
@State var show2 = false
@State var show3 = false
var body: some View {
ZStack {
NavigationView {
VStack {
Section {
Color(red: 0.88, green: 0.88, blue: 0.88)
.frame(maxWidth: .infinity, maxHeight: .infinity).edgesIgnoringSafeArea(.all)
HStack {
Button(action: {
withAnimation(.spring())
{
self.show1.toggle()
}
}) {
Text("View1")
.font(.headline)
.fontWeight(.regular)
.lineLimit(nil)
.padding(EdgeInsets.init(top: -5, leading: 15, bottom: 0, trailing: 15))
.foregroundColor(show1 ? .blue : .gray)
}.foregroundColor(show1 ? .blue : .gray)
.padding()
Button(action: {
withAnimation(.spring())
{
self.show2.toggle()
}
}) {
Text("View2")
.font(.headline)
.fontWeight(.regular)
.lineLimit(nil)
.padding(EdgeInsets.init(top: -5, leading: 15, bottom: 0, trailing: 15))
.foregroundColor(show2 ? .blue : .gray)
}.foregroundColor(show2 ? .blue : .gray)
.padding()
Button(action: {
withAnimation(.spring())
{
self.show3.toggle()
}
}) {
Text("View3")
.font(.headline)
.fontWeight(.regular)
.lineLimit(nil)
.padding(EdgeInsets.init(top: -5, leading: 15, bottom: 0, trailing: 10))
.foregroundColor(show3 ? .blue : .gray)
}.foregroundColor(show3 ? .blue : .gray)
.padding()
}}}
}
VStack (alignment: .center) {
if self.show1 {
ShowView1().transition(
AnyTransition.move(edge: .bottom).combined(with: .move(edge: .bottom)).combined(with: .opacity))
}
}
VStack (alignment: .center) {
if self.show2 {
ShowView2().transition(
AnyTransition.move(edge: .bottom).combined(with: .move(edge: .bottom)).combined(with: .opacity))
}
}
VStack (alignment: .center) {
if self.show3 {
ShowView3().transition(
AnyTransition.move(edge: .bottom).combined(with: .move(edge: .bottom)).combined(with: .opacity))
}
}}}}
struct ShowView1: View {
var body: some View {
ZStack() {
Color.white
.frame(maxWidth: .infinity, maxHeight: 52)
}
}
}
struct ShowView2: View {
var body: some View {
ZStack() {
Color.white
.frame(maxWidth: .infinity, maxHeight: 600)
}
}
}
struct ShowView3: View {
var body: some View {
ZStack() {
Color.white
.frame(maxWidth: .infinity, maxHeight: 300)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
You actually not switch but toggle each view, so have as a result coexisting views. Here is corrected part of code (only switching logic). Tested with Xcode 11.2 / iOS 13.2.
struct ContentView: View {
@State var selectedView: Int? = nil
var body: some View {
ZStack {
NavigationView {
VStack {
Section {
Color(red: 0.88, green: 0.88, blue: 0.88)
.frame(maxWidth: .infinity, maxHeight: .infinity).edgesIgnoringSafeArea(.all)
HStack {
Button(action: {
withAnimation(.spring())
{
self.selectedView = 1
}
}) {
Text("View1")
.font(.headline)
.fontWeight(.regular)
.lineLimit(nil)
.padding(EdgeInsets.init(top: -5, leading: 15, bottom: 0, trailing: 15))
.foregroundColor(self.selectedView == 1 ? .blue : .gray)
}.foregroundColor(self.selectedView == 1 ? .blue : .gray)
.padding()
Button(action: {
withAnimation(.spring())
{
self.selectedView = 2
}
}) {
Text("View2")
.font(.headline)
.fontWeight(.regular)
.lineLimit(nil)
.padding(EdgeInsets.init(top: -5, leading: 15, bottom: 0, trailing: 15))
.foregroundColor(self.selectedView == 2 ? .blue : .gray)
}.foregroundColor(self.selectedView == 2 ? .blue : .gray)
.padding()
Button(action: {
withAnimation(.spring())
{
self.selectedView = 3
}
}) {
Text("View3")
.font(.headline)
.fontWeight(.regular)
.lineLimit(nil)
.padding(EdgeInsets.init(top: -5, leading: 15, bottom: 0, trailing: 10))
.foregroundColor(self.selectedView == 3 ? .blue : .gray)
}.foregroundColor(self.selectedView == 3 ? .blue : .gray)
.padding()
}}}
}
VStack (alignment: .center) {
if self.selectedView == 1 {
ShowView1().transition(
AnyTransition.move(edge: .bottom).combined(with: .move(edge: .bottom)).combined(with: .opacity))
}
if self.selectedView == 2 {
ShowView2().transition(
AnyTransition.move(edge: .bottom).combined(with: .move(edge: .bottom)).combined(with: .opacity))
}
if self.selectedView == 3 {
ShowView3().transition(
AnyTransition.move(edge: .bottom).combined(with: .move(edge: .bottom)).combined(with: .opacity))
}
}}}}