oscar
oscar

Reputation: 111

Swift return random element from array into text

This problem which I know should be very easy has stumped me for hours.

I try to get a random element from a simple Array into a Text in SwiftUI but i get errors I don't understand, the recent error I got was:

Instance method 'appendInterpolation' requires that '[Result]' conform to '_FormatSpecifiable'

What would be the simplest way to implement this? I understand this has been answered many times but I am too bad at coding to understand when I try to google it.

struct Result: Identifiable {
    var id = UUID()
    var score: Int
}

struct ContentView: View {

    @State private var showDetails = false

    @State var results = [Result(score: 8),
                          Result(score: 5),
                          Result(score: 10)]


    var body: some View {
        VStack {
            Button(action: {   
                self.results.randomElement()
            }) {
                Text("Button title, \(results)")
            }

        }
    }
}

Upvotes: 1

Views: 948

Answers (1)

Alladinian
Alladinian

Reputation: 35636

Since results aren't changing, there's no need for @State (coupled with an initializer on Result so we can easily map a list of scores). Instead, we want to introduce a new variable to hold a random Result and mark that as a state. So each time we press the button, we set a new random result and trigger a view update.

Please note that I have marked the var as optional (since I do not know the logic behind any initial value) and displaying a 0 if this thing is nil (probably not what you want in your final code - you can decide whatever default value, or conditional view display, makes sense for you)

struct Result: Identifiable {
    var id = UUID()
    var score: Int
    init(_ score: Int) {
        self.score = score
    }
}

struct ContentView: View {

    @State private var showDetails = false

    let results = [8, 5, 10].map(Result.init)

    @State var randomResult: Result?

    var body: some View {
        VStack {
            Button(action: {   
                self.randomResult = self.results.randomElement()
            }) {
                Text("Button title, \(randomResult?.score ?? 0)")
            }
        }
    }
}

Upvotes: 1

Related Questions