Search code examples
swiftmvvmswiftuixcode12

How do I access a random value from the restaurantList each time I tap the randomize button


struct RandomizeTab: View {
    
    var restaurantInfo = Restaurants()
    
    var body: some View {
        
        NavigationView {
            NavigationLink(
                destination: DetailView(restaurantInfo: restaurantInfo.restaurantList[Int.random(in: 0...restaurantInfo.restaurantList.count-1)]),
                label: {
                    Text("Randomize")
                        .font(.title3)
                        .fontWeight(.bold)
                        .padding()
                        .background(Color.red)
                        .foregroundColor(.white)
                        .clipShape(Capsule())
                })
            
        }

    }
}

Currently, this code chooses one random restaurant from the list and doesn't choose a new random restaurant from the list each time I tap it.


Solution

  • NavigationLink destinations are calculated on the first render of the view. So, your random calculation will only be called once. One solution to that is to use a NavigationLink that lazily loads the view. There's a StackOverflow answer that I've borrowed that from: (https://stackoverflow.com/a/61234030/560942)

    
    struct ContentView : View {
        var elements = [1,2,3,4,5,6,7]
        
        var body: some View {
            NavigationView {
                NavigationLink(destination:
                                NavigationLazyView(DetailView(input: elements.randomElement()!))
                ) {
                    Text("Go to random")
                }
            }
        }
    }
    
    struct NavigationLazyView<Content: View>: View {
        let build: () -> Content
        init(_ build: @autoclosure @escaping () -> Content) {
            self.build = build
        }
        var body: Content {
            build()
        }
    }
    
    struct DetailView : View {
        var input : Int
        
        var body: some View {
            Text("\(input)")
        }
    }
    

    Now, the content is calculated lazily and so the random calculation is done each time.