JustMe
JustMe

Reputation: 145

How can I use the same randomly generated number twice? - SwiftUI

I'm trying to build a very simple multiplication practice app where the user picks the multiplication table they want to practice and the app poses multiplication problems on that table using a randomly generated integer between 1 and 20. I then want to give the user the answer.

The problem that I'm having is that the randomly generated number changes between my code for showing the question and my code for showing the answer. I'm sure there's a simple solution to this, but I'm not seeing it.

How do I store a randomly generated number for use in two places in my code? Alternatively, how do I selectively stop the randomization from happening?

Here's my current code:

    struct test: View {

  @State private var multiplicationTable = 1

  var body: some View {
    VStack {
      Spacer()
      Text("Pick the multiplication table you'd like to practice!")
        .bold()
        .fontWeight(.bold)
        .font(.title)

        .multilineTextAlignment(.center)
      Stepper(value: $multiplicationTable, in: 1...12, step: 1) {
        Text("\(multiplicationTable)'s")
      }
      Text("Let's go!")
      Spacer()
      Text("Question #1: \(numberForText(multiplier1: multiplicationTable).text1)")
      Text("Answer: \(numberForText(multiplier1: multiplicationTable).text2)")
      Spacer()
    }
    .padding(.leading, 20)
    .padding(.trailing, 20)
  }

  func numberForText(multiplier1: Int) -> (text1: String, text2: String) {
    let multiplier2 = Int.random(in: 1..<21)
    return ("What is \(multiplier1) times \(multiplier2)?", "\(multiplier1) times \(multiplier2) = \(multiplier1 * multiplier2)")
  }
}

Thank you.

Upvotes: 1

Views: 80

Answers (2)

Glenn Posadas
Glenn Posadas

Reputation: 13290

You will need to get data from your numberForText method just once. And store the returned tuple to a property. That's it!

struct test: View {

    @State private var multiplicationTable = 1

    @State private var generatedTuple: (text1: String, text2: String) = ("", "")

    var body: some View {
        VStack {
            Spacer()
            Text("Pick the multiplication table you'd like to practice!")
                .bold()
                .fontWeight(.bold)
                .font(.title)
                .multilineTextAlignment(.center)

            Stepper(value: $multiplicationTable, in: 1...12, step: 1, onEditingChanged: { (didChange) in
                self.generatedTuple = self.numberForText(multiplier1: self.multiplicationTable)
            }) {
                Text("\(multiplicationTable)'s")
            }

            Text("Let's go!")
            Spacer()

            Text("Question #1: \(self.generatedTuple.text1)")
            Text("Answer: \(self.generatedTuple.text2)")

            Spacer()
        }
        .padding(.leading, 20)
        .padding(.trailing, 20)
    }

    func numberForText(multiplier1: Int) -> (text1: String, text2: String) {
        let multiplier2 = Int.random(in: 1..<21)
        return ("What is \(multiplier1) times \(multiplier2)?", "\(multiplier1) times \(multiplier2) = \(multiplier1 * multiplier2)")
    }
}

As you can see, I make use of Stepper's onEditingChanged closure event. Inside that event, I call on your numberForText method, and the returned tuple is stored in the property:

@State private var generatedTuple: (text1: String, text2: String) = ("", "").

And the Text values for Question and Answer will be the data from the stored tuple - and you already know how to extract them.

Upvotes: 2

Asperi
Asperi

Reputation: 258177

You just need to store generated pair question-answer. Please find below possible approach:

struct test: View {

  @State private var multiplicationTable = 1

    @State private var excesize: (text1: String, text2: String) = ("", "")
  var body: some View {
    VStack {
      Spacer()
      Text("Pick the multiplication table you'd like to practice!")
        .bold()
        .fontWeight(.bold)
        .font(.title)

        .multilineTextAlignment(.center)
      Stepper(value: $multiplicationTable, in: 1...12, step: 1) {
        Text("\(multiplicationTable)'s")
      }
      Text("Let's go!")
      Spacer()
      Text("Question #1: \(excesize.text1)")
      Text("Answer: \(excesize.text2)")
      Spacer()
        Button("Next turn") { self.generateNext() }
    }
    .padding(.leading, 20)
    .padding(.trailing, 20)
  }

    func generateNext() {
        self.excesize = numberForText(multiplier1: multiplicationTable)
    }

  func numberForText(multiplier1: Int) -> (text1: String, text2: String) {
    let multiplier2 = Int.random(in: 1..<21)
    return ("What is \(multiplier1) times \(multiplier2)?", "\(multiplier1) times \(multiplier2) = \(multiplier1 * multiplier2)")
  }
}

Upvotes: 1

Related Questions