I have 2 Integers: Xcode and Ycode. These are bindings from previous screens. Now what I want is to present a new view based on these integers.
The app is a small quiz. So the Xcode and Ycode are the score. But I want to present a new view when you click on the button "Click me" based on the Xcode and Ycode.
For example:
Value X = between 8-15 and value Y = between 8-23 -> present screen1
Value X = between 8-15 and value Y = between 24-40 -> present screen2
Value X = between 16-23 and value Y = between 8-17 -> present screen3
And so on......
This is my Code:
@Binding var Xcode: Int
@Binding var Ycode: Int
@State var ShowButton: Bool = false
@State var ButtonYes: Bool = false
@State var ButtonNo: Bool = false
@State var ButtonSometimes: Bool = false
var body: some View {
ZStack{
Image("Zebras")
.resizable()
.ignoresSafeArea()
.navigationBarHidden(true)
VStack{
Text("Wat ben ik?")
.font(.largeTitle)
.fontWeight(.heavy)
.padding()
.foregroundColor(.white)
.background(Color(red: 0.493, green: 0.184, blue: 0.487))
.cornerRadius(20)
Spacer()
Text("Je heb alle vragen beantwoord. Nu is de vraag: Welk dier ben ik?")
.foregroundColor(Color.white)
.font(.headline)
.padding()
.background(Color(red: 0.493, green: 0.184, blue: 0.487))
.cornerRadius(20)
Spacer()
Text("Your score:")
.foregroundColor(Color.white)
.font(.headline)
.padding()
.background(Color(red: 0.493, green: 0.184, blue: 0.487))
.cornerRadius(20)
HStack (spacing:0){
Text("X = ")
.foregroundColor(.white)
.font(.largeTitle)
.padding()
.background(Color(red: 0.493, green: 0.184, blue: 0.487))
.cornerRadius(20)
Text(String(Xcode))
.foregroundColor(.white)
.font(.largeTitle)
.padding()
.background(Color(red: 0.493, green: 0.184, blue: 0.487))
.cornerRadius(20)
}
HStack (spacing:0){
Text("Y = ")
.foregroundColor(.white)
.font(.largeTitle)
.padding()
.background(Color(red: 0.493, green: 0.184, blue: 0.487))
.cornerRadius(20)
Text(String(Ycode))
.foregroundColor(.white)
.font(.largeTitle)
.padding()
.background(Color(red: 0.493, green: 0.184, blue: 0.487))
.cornerRadius(20)
}
Spacer()
Button("Click here!") {
}
.frame(width: 100, height: 50, alignment: .center)
.font(.headline)
.foregroundColor(.white)
.padding()
.background(ButtonYes ? Color(red: 0.272, green: 0.471, blue: 0.262) : Color(red: 0.493, green: 0.184, blue: 0.487))
.cornerRadius(20)
.shadow(color: .black, radius: 10, x: 10, y: 10)
Spacer()
}
}
}
}
How could I create that?
CodePudding user response:
you could use this approach, using a tuple, a switch and some NavigationLinks:
struct ContentView: View {
@State var xy = (5.0,7.0) // <-- use a tuple
var body: some View {
NavigationView {
QuizView(xy: $xy)
}.navigationViewStyle(.stack)
}
}
struct QuizView: View {
@Binding var xy: (Double, Double)
// set of ranges of your scores for each screen
let screen1X = 1.0..<4.0
let screen1Y = 2.0..<4.0
let screen2X = 3.0..<4.0
let screen2Y = 4.0..<8.0
let screen3X = 5.0..<9.0
let screen3Y = 6.0..<8.0
@State private var action: Int? = 0
var body: some View {
VStack {
Button(action: {
switch xy {
case (screen1X,screen1Y): action = 1
case (screen2X,screen2Y): action = 2
case (screen3X,screen3Y): action = 3
default:
print("---> default")
}
}) {
Text("Click me")
}
NavigationLink(destination: Text("screen1X"), tag: 1, selection: $action) {EmptyView()}
NavigationLink(destination: Text("screen2X"), tag: 2, selection: $action) {EmptyView()}
NavigationLink(destination: Text("screen3X"), tag: 3, selection: $action) {EmptyView()}
}
}
}
CodePudding user response:
You could have hidden navigation links like these:
NavigationLink(destination: View1(), isActive: $condition1, label: { EmptyView() })
NavigationLink(destination: View2(), isActive: $condition2, label: { EmptyView() })
NavigationLink(destination: View3(), isActive: $condition3, label: { EmptyView() })
// note that having empty views for your links will keep them hidden on your layout
for each of your X and Y conditions.
So, when you check for X and Y values, you could verify them like this:
condition1 = Xcode >= 8 && Xcode <= 15 && Ycode >= 8 && Code <= 23
condition2 = Xcode >= 8 && Xcode <= 15 && Ycode >= 24 && Code <= 40
condition3 = Xcode >= 16 && Xcode <= 23 && Ycode >= 8 && Code <= 17
and that would activate the link you want and present the screen you need.
CodePudding user response:
ContentView with 2 values: valueX and valueY. Then the ranges you need. Then a computed property to decide to which screen should navigate. The button is only created if the computed property doesn't return nil. And the destination of the navigation link has a switch which decides the screen to show and a label that is the button to be clicked.
import SwiftUI
struct MContentView: View {
@State var valueX = 17
@State var valueY = 15
@State var isNextViewActive = false
private let range8_15 = 8...15
private let range16_23 = 16...23
private let range8_23 = 8...23
private let range24_40 = 24...40
private let range8_17 = 8...17
private var screenToPresent: Int? {
if range8_15.contains(valueX) && range8_23.contains(valueY) {
return 1
} else if range8_15.contains(valueX) && range24_40.contains(valueY) {
return 2
} else if range16_23.contains(valueX) && range8_17.contains(valueY) {
return 3
}
return nil
}
var body: some View {
NavigationView {
if let screen = self.screenToPresent {
NavigationLink(isActive: self.$isNextViewActive, destination: {
switch screen {
case 1:
MView1()
case 2:
MView2()
case 3:
MView3()
default:
EmptyView()
}
}) {
Button(action: {
self.isNextViewActive = true
}) {
Text("Click me!")
}
}
}
}
}
}
struct MView1: View {
var body: some View {
Text("My View 1")
}
}
struct MView2: View {
var body: some View {
Text("My View 2")
}
}
struct MView3: View {
var body: some View {
Text("My View 3")
}
}
struct MExample_Previews: PreviewProvider {
static var previews: some View {
MContentView()
}
}
Hope is what you are looking for!