I'm new to coding having done very little of it previously, and am yet again trying to learn how to code using Swift / SwiftUI.
Although I do have a simple app idea that I don't expect will ever make any money but it will fill a particular need of mine and hopefully others in my position.
For the UI of my app I'd like to display different views depending on what the user wants to do and I have the idea to present these views in a circular design and "flip" the circle over as each view is required.
I've looked at a few different "flip animation" tutorials and they all seem to focus on just two views, and flipping between them (ie like a playing card) but what I need is to have an arbitrary number of views and flip between any given two.
I thought I had it with my last attempt but the results are unexpected (to me) and I'm struggling to follow why. Which is probably my fault, as I used a function from one of the tutorials that flips between just two views. Here is my (admittedly messy I know) code. I know there will be tons of things I've done wrong, and better ways of doing things so please don't be too hard on me :)
struct tealView : View {
@Binding var degree : Double
var body: some View {
ZStack{
Group {
Circle()
.frame(width: 350, height: 350)
.foregroundColor(Color(.systemTeal))
Text("Teal View!")
}
}.rotation3DEffect(Angle(degrees: degree), axis: (x: 0, y: 1, z: 0), anchor: .center, anchorZ: 0, perspective: 0.2)
}
}
struct redView : View {
@Binding var degree : Double
var body: some View {
ZStack {
Group {
Circle()
.frame(width: 350, height: 350)
.foregroundColor(Color(.systemRed))
Text("Red View!")
}
}.rotation3DEffect(Angle(degrees: degree), axis: (x: 0, y: 1, z: 0), anchor: .center, anchorZ: 0, perspective: 0.2)
}
}
struct blueView : View {
@Binding var degree : Double
var body: some View {
ZStack {
Group {
Circle()
.frame(width: 350, height: 350)
.foregroundColor(Color(.systemBlue))
Text("Blue View!")
}
}.rotation3DEffect(Angle(degrees: degree), axis: (x: 0, y: 1, z: 0), anchor: .center, anchorZ: 0, perspective: 0.2)
}
}
struct yellowView : View {
@Binding var degree : Double
var body: some View {
ZStack {
Group {
Circle()
.frame(width: 350, height: 350)
.foregroundColor(Color(.systemYellow))
Text("Yellow View!")
}
}.rotation3DEffect(Angle(degrees: degree), axis: (x: 0, y: 1, z: 0), anchor: .center, anchorZ: 0, perspective: 0.2)
}
}
struct ContentView: View {
@State var backDegree = 0.0
@State var frontDegree = -90.0
@State var isFlipped = false
@State private var tealFront = true
@State private var redFront = false
@State private var blueFront = false
@State private var yellowFront = false
@State private var tealWasFront = false
@State private var redWasFront = true
@State private var blueWasFront = false
@State private var yellowWasFront = false
let durationAndDelay : CGFloat = 0.45
func flipcard () {
isFlipped = !isFlipped
if isFlipped {
withAnimation(.easeInOut(duration: durationAndDelay)) {
backDegree = 90
}
withAnimation(.easeInOut(duration: durationAndDelay).delay(durationAndDelay)){
frontDegree = 0
}
} else {
withAnimation(.easeInOut(duration: durationAndDelay)) {
frontDegree = -90
}
withAnimation(.easeInOut(duration: durationAndDelay).delay(durationAndDelay)){
backDegree = 0
}
}
}
var body: some View {
VStack {
ZStack {
if tealFront {
tealView(degree: $frontDegree)
if yellowWasFront {
yellowView(degree: $backDegree)
} else if redWasFront {
redView(degree: $backDegree)
} else {
blueView(degree: $backDegree)
}
} else if redFront {
redView(degree: $frontDegree)
if yellowWasFront {
yellowView(degree: $backDegree)
} else if tealWasFront {
tealView(degree: $backDegree)
} else {
blueView(degree: $backDegree)
}
} else if blueFront {
blueView(degree: $frontDegree)
if yellowWasFront {
yellowView(degree: $backDegree)
} else if redWasFront {
redView(degree: $backDegree)
} else {
tealView(degree: $backDegree)
}
} else {
yellowView(degree: $frontDegree)
if tealWasFront {
tealView(degree: $backDegree)
} else if redWasFront {
redView(degree: $backDegree)
} else {
blueView(degree: $backDegree)
}
}
}
.padding(20)
HStack {
Group {
Button {
if !tealFront { tealFront = true }
if redFront {
redFront = false
redWasFront = true
blueWasFront = false
yellowWasFront = false
tealWasFront = false
}
if blueFront { blueFront = false
blueWasFront = true
redWasFront = false
yellowWasFront = false
tealWasFront = false
}
if yellowFront { yellowFront = false
yellowWasFront = true
blueWasFront = false
redWasFront = false
tealWasFront = false
}
flipcard()
} label: {
ZStack {
Circle()
.foregroundColor(Color(.systemTeal))
Text("Teal")
.foregroundColor(Color.black)
}
}
}
Group {
Button {
if !redFront { redFront = true }
if tealFront {
tealFront = false
tealWasFront = true
blueWasFront = false
yellowWasFront = false
redWasFront = false
}
if blueFront { blueFront = false
blueWasFront = true
yellowWasFront = false
tealWasFront = false
redWasFront = false
}
if yellowFront { yellowFront = false
yellowWasFront = true
blueWasFront = false
tealWasFront = false
redWasFront = false
}
flipcard()
} label: {
ZStack {
Circle()
.foregroundColor(Color(.systemRed))
Text("Red")
.foregroundColor(Color.black)
}
}
}
Group {
Button {
if !blueFront { blueFront = true }
if redFront {
redFront = false
redWasFront = true
tealWasFront = false
yellowWasFront = false
blueWasFront = false
}
if tealFront { tealFront = false
tealWasFront = true
redWasFront = false
yellowWasFront = false
blueWasFront = false
}
if yellowFront { yellowFront = false
yellowWasFront = true
tealWasFront = false
redWasFront = false
blueWasFront = false
}
flipcard()
} label: {
ZStack {
Circle()
.foregroundColor(Color(.systemBlue))
Text("Blue")
.foregroundColor(Color.black)
}
}
}
Group {
Button {
if !yellowFront { yellowFront = true }
if redFront {
redFront = false
redWasFront = true
blueWasFront = false
tealWasFront = false
yellowWasFront = false
}
if blueFront { blueFront = false
blueWasFront = true
redWasFront = false
tealWasFront = false
yellowWasFront = false
}
if tealFront { tealFront = false
tealWasFront = true
blueWasFront = false
redWasFront = false
yellowWasFront = false
}
flipcard()
} label: {
ZStack {
Circle()
.foregroundColor(Color(.systemYellow))
Text("Yellow")
.foregroundColor(Color.black)
}
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}