Search code examples
swiftswiftuiswiftui-navigationlink

Is there a way to use NavigationLink() on SwiftUI to go to a random view?


I am trying to use the NavigationLink() Button to go to one of four views, and I want it to be random.

I tried to use a random variable and the switch function, but it turns out that I cannot modify the variable inside the NavigationLink() button (it gives me this error: Type '()' cannot conform to 'View') like I would in a normal button. This is what I got:

import SwiftUI

struct ContentView: View { @State var valore = Int.random(in: 1...4)

var body: some View {
    NavigationStack {
        NavigationLink {
            switch valore {
            case 1:
                ContentView1()
            case 2:
                ContentView2()
            case 3:
                ContentView3()
            case 4:
                ContentView4()
            default:
                ContentView()
            }
            } label: {
                Image("Retro")
                    .resizable()
                    .cornerRadius(27.0)
                    .aspectRatio(contentMode: .fit)
                    .padding()
            }
        Text("\(valore)")
            .bold()
            .font(.title)
    }
}

} I would like to "re-randomize" the variable 'valore' inside each case so that when it goes back the number has changed, and so the view that it will go to next.


Solution

  • You can take advantage of Property Wrappers.

    On your ContentView1...4, declare a Binding var on each one like this below:

    @Binding var valore: Int
    

    Inside each ContentView1...4 add a .onAppear and update the value there:

    struct ContentView1: View {
        @Binding var valore: Int
        
        var body: some View {
            VStack {
                Text("Content 1")
            }
            .onAppear {
                valore = Int.random(in: 1...4)
            }
        }
    }
    

    This will automatically change the valore value.

    Your ContentView should look like this:

    struct ContentView: View {
    @State private var valore = Int.random(in: 1...4)
    
    var body: some View {
        NavigationStack {
            NavigationLink {
                switch valore {
                case 1:
                    ContentView1(valore: $valore)
                case 2:
                    ContentView2(valore: $valore)
                case 3:
                    ContentView3(valore: $valore)
                case 4:
                    ContentView4(valore: $valore)
                default:
                    ContentView1(valore: $valore)
                }
            } label: {
                Image("Retro")
                    .resizable()
                    .cornerRadius(27.0)
                    .aspectRatio(contentMode: .fit)
                    .padding()
            }
            Text("\(valore)")
                .bold()
                .font(.title)
        }
    }
    

    Hope it helps