Note: the ForEach I talk about is the one in GameView, not KeyboardView
My app is a form of the game hangman, I have getLetters( ) get a random word from an array and split it into letters. I then have those letters displayed as lines using a ForEach until the user selects the corresponding letter on the keyboard view. This is done by adding the letter pressed into an array and the comparing to see if the letter in the ForEach is the same and if so, it is changed to the letter.
What I’m having trouble with is that sometimes when the correct letter button has been pressed, the ForEach does not update. I believe that has something to do with the ForEach using ‘id: .self’ as the issue only happens in words that have 2 or more of the same letter, though for some reason it almost always happens to the last letter of the word, even if not picked last.
If there is more information I can include either ask me and ill add it or check out the project files I’ve added.
class GameLetters: ObservableObject {
@Published var usedLetters = [String]()
@Published var gameLetters:Array = getLetters()
@Published var correctLetters = [Character]()
@Published var incorrectLetters = [Character]()
static func getLetters() -> Array<Character> {
let allWords = WordList.wordList
let randomWord : String! = allWords.randomElement()
let letters = Array(randomWord)
return letters
}
}
struct GameView: View {
@ObservedObject var vm: GameLetters //@StateObject used in above view
var body: some View {
ForEach(vm.gameLetters, id: \.self) { letter in
if vm.correctLetters.contains(letter) {
Text(String(letter))
font(.system(size: 35, weight: .medium))
} else {
RoundedRectangle(cornerRadius: 10)
.frame(width: 25, height: 4)
.offset(y: 10)
}
}
}
}
struct KeyboardView: View {
@ObservedObject var vm: GameLetters
@State private var letters = KeyboardLetters()
var body: some View {
…
ForEach(letters.allLetters, id: \.self) { letter in
Button {
vm.usedLetters.append(letter)
if vm.gameLetters.contains(Character(letter)) {
vm.correctLetters.append(Character(letter))
if checkLetters() == true {
print("game won")
}
} else {
vm.incorrectLetters.append(Character(letter))
}
} label: {
…
}
func checkLetters() -> Bool {
if vm.gameLetters == vm.correctLetters {
return true
} else {
return false
}
}
}
struct KeyboardLetters {
let allLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
}
Post
Replies
Boosts
Views
Activity
I have a ForEach loop that outputs an array of characters of a phrase, how would I be able to make it that the ForEach goes to the next line when the character is a space?