import SwiftUI
struct ContentView: View {
@State private var fiveNumbers: Set<Int> = []
@State private var twoNumbers: Set<Int> = []
// there has to be a better way to copy a Set instead of making it a string like this. it includes brackets too....
// options: remove all [] from string OR find another way to get the numbers into the boxes without being a string
@State private var fiveSentence = ""
@State private var twoSentence = ""
var body: some View {
NavigationStack {
Form {
Button("Faz o meu Euromilhões") {
fiveNumbers.removeAll()
twoNumbers.removeAll()
while fiveNumbers.count < 5 {
let newRandomNumber = Int.random(in: 1...50)
fiveNumbers.insert(newRandomNumber)
}
let sortedNumbers = fiveNumbers.sorted()
fiveSentence = "\(sortedNumbers)"
while twoNumbers.count < 2 {
let newRandomNumber = Int.random(in: 1...12)
twoNumbers.insert(newRandomNumber)
}
let sortedTwoNumbers = twoNumbers.sorted()
twoSentence = "\(sortedTwoNumbers)"
}
Section("Números") {
Text(fiveSentence)
}
Section("Estrelas") {
Text(twoSentence)
}
}
.navigationTitle("Euromilhões")
.toolbar {
if !fiveNumbers.isEmpty {
Button("Limpar") {
fiveSentence.removeAll()
twoSentence.removeAll()
fiveNumbers.removeAll()
twoNumbers.removeAll()
}
}
}
}
}
}
Let me preface this by saying I have no experience in coding and I'm an absolute beginner. This is a throwaway project I'm tinkering with after 1 week of 100 days of Swift.
- Q1: Is this ok, or should I compute (not sure if this is the correct term?) outside of the body for the button:
Button("Faz o meu Euromilhões")
Q2: I tried to be "smart" and use
@State private var fiveNumbers: Set<Int> = []
instead of
@State private var fiveNumbers: [Int] = []
to avoid having to write more code to not get repeated numbers. if !fiveNumbers.contain(newRandomNumber) { fiveNumbers.append(newRandomNumber) }
but how can I get the array into Text
without brackets?
Thank you so much for your time and patience!
Q1: The way you are doing it is formally “okay”. It does not violate the way SwiftUI works. You are not really computing inside the body
of ContentView
. Instead, you are passing a “closure” (a function) to the Button
. The Button
saves the closure and runs it later, when it (the Button
) is tapped. That’s when the computation happens.
The way you are doing it is also “okay” for a toy project, where you don’t intend to keep the code around for a long time and you don’t intend to write test cases.
If this were a serious project, you would want to factor that code out into a standalone function so that you could write tests for it.
Q2: Here’s one way to turn a Set<Int>
into a Text
:
Text(
fiveNumbers
.sorted()
.formatted(ListFormatStyle(memberStyle: .number))
)
Here’s another way:
Text(
fiveNumbers
.sorted()
.map { "\($0)"}
.joined(separator: ", ")
)