I apologize if this code is ugly. I'm completely-blind and just finished 100 Days of SwiftUI about a month ago.
/*
I was trying to keep my code sample small to keep the post short I instantiate these buttons in a parent view, where I was originally initializing every button needed and storing them in an array. I was told in some Swift Facebook groups that storing an array of these buttons in the parent view is bad practice, so I’ve track these buttons by their data instead. I’ll include the actual code this time, so I apologize for the lengthier post.
First, here’s the button type:
Struct CustomButton: View {
@ObservedObject var hiddenButtonData: HiddenButtonData
private(set) var name: String
@State var shouldBeHidden = false {
didSet {
print("shouldBeHidden changed to \(shouldBeHidden) for button with name \(name)")
if shouldBeHidden == true{
hiddenButtonData.add(dataFrom: self)
}//conditional
}//didset
}//shouldBeHidden
//These two values are set in letterGroupButton view so we can track where the button needs to be added back-in when the currentSpelling is cleared.
let parentRowIndex: Int
let indexInParentRow: Int
init(allSettings: AllSettings, hiddenButtonData: HiddenButtonData, name: String, parentRowIndex: Int, indexInParentRow: Int) {
self.allSettings = allSettings
self.hiddenButtonData = hiddenButtonData
self.name = name.uppercased()
self.parentRowIndex = parentRowIndex
self.indexInParentRow = indexInParentRow
}//init
var body: some View {
Button(self.name) {
hiddenButtonData.add(dataFrom: self)
shouldBeHidden = true
}//Button
.disabled(shouldBeHidden)
.accessibility(hidden: shouldBeHidden)
}//body
}//struct
Now, here's the class that tracks hidden button data
class HiddenButtonData: ObservableObject {
@Published private(set) var names = [String]()
@Published private(set) var coordinates = [[Int: Int]]()
//Methods
func add(dataFrom: LetterGroupButton) {
names.append(dataFrom.name)
coordinates.append([dataFrom.parentRowIndex: dataFrom.indexInParentRow])
print("HiddenButtonData just added \(dataFrom.name) to itself")
}//add
func clearStoredData() {
names.removeAll()
coordinates.removeAll()
}//clearStoredData
}//class
And finally, here's the parent view where the buttons are instantiated, and where I attempt to enable some of the buttons again.
struct ContentView: View {
@StateObject private var hiddenButtonData = HiddenButtonData()
var body -> some View {
List {
ForEach(initializeAllButtons(), id: \.self.indexInParentRow) { buttonData in
LetterGroupButton(allSettings: allSettings, hiddenButtonData: hiddenButtonData, name: buttonData.name, parentRowIndex: dataSet.indexInArrayOfRows, indexInParentRow: buttonData.indexInParentRow, currentSpellingInActivePuzzle: $currentSpelling)
}//loop
}//List
.background(.clear)
Button("Restore Button Visibility") {
restoreVisibilityOfHiddenButtons()
}//button
}//body
//methods
func initializeAllButtons() -> [CustomButton] {
// some code that initializesCustomButton instances from JSON data
}//initializeAllButtons
func restoreVisibilityOfHiddenButtons() {
print("calling restore visibility")
for dictionary in hiddenButtonData.coordinates {
//These key: value pairs represent the rows index, then the button index in the row
for (key, value) in dictionary {
rowsOfButtonsData[key].allButtonData[value].setShouldBeHidden(false)
print("restoreVisibility should have just changed shouldBeHidden for \(rowsOfButtonsData[key].allButtonData[value].name)")
}//nested loop
}//loop
hiddenButtonData.clearStoredData()
}//restoreVisibilityOfHiddenButtons
}//struct
*/