Accessing Existing Button with Tag?

I have a button (Click me) at the top. And it's followed by some space and stacks of buttons that are horizontally laid out as follows.

Code Block
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
VStack(spacing: 0.0) {
Button("Click me", action: {
})
Spacer()
.frame(height: 20)
HStack(spacing: 0.0) {
ForEach((0...6), id: \.self) {
Button("") {
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
...
...
...
HStack(spacing: 0.0) {
ForEach((28...34), id: \.self) {
Button("") {
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
HStack(alignment: .top, spacing: 0.0) {
ForEach((35...36), id: \.self) {
Button("") {
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
.frame(width: 336.0, height: 48.0, alignment: .leading)
}
}
}
}


None of the buttons except the very top one has a title as you see above. And I want to set a title to each button and show or hide any of them when necessary. So is it possible for me to access any of the buttons with its tag and set its title and show or hide it? Thank you.
Answered by OOPer in 652272022

how it could be done without the tag

For example, I would write something like this:
Code Block
import SwiftUI
struct ContentView: View {
@State var buttonTitles: [String?] = Array(repeating: nil, count: 37) //<- Change `count` as the number you need
var body: some View {
ZStack {
VStack(spacing: 0.0) {
Button("Click me", action: {
})
Spacer()
.frame(height: 20)
HStack(spacing: 0.0) {
ForEach((0...6), id: \.self) {
Button(buttonTitles[$0] ?? "") { //<-
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
//...
//...
//...
HStack(spacing: 0.0) {
ForEach((28...34), id: \.self) {
Button(buttonTitles[$0] ?? "") { //<-
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
HStack(alignment: .top, spacing: 0.0) {
ForEach((35...36), id: \.self) {
Button(buttonTitles[$0] ?? "") { //<-
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
.frame(width: 336.0, height: 48.0, alignment: .leading)
}
}
}
}


Generally in SwiftUI, you should not try to modify the view content by touching each view, but you should define a source of truth for the views and modify the source.

it possible for me to access any of the buttons with its tag

Sorry, I have never tried and I do not know.

is it possible for me to set its title and show or hide it?

If you do not insist on using tags, the answer would be YES.
Thanks, OOper. No, I don't insist on using tags. Could you give me some idea of how it could be done without the tag, please?
Accepted Answer

how it could be done without the tag

For example, I would write something like this:
Code Block
import SwiftUI
struct ContentView: View {
@State var buttonTitles: [String?] = Array(repeating: nil, count: 37) //<- Change `count` as the number you need
var body: some View {
ZStack {
VStack(spacing: 0.0) {
Button("Click me", action: {
})
Spacer()
.frame(height: 20)
HStack(spacing: 0.0) {
ForEach((0...6), id: \.self) {
Button(buttonTitles[$0] ?? "") { //<-
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
//...
//...
//...
HStack(spacing: 0.0) {
ForEach((28...34), id: \.self) {
Button(buttonTitles[$0] ?? "") { //<-
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
HStack(alignment: .top, spacing: 0.0) {
ForEach((35...36), id: \.self) {
Button(buttonTitles[$0] ?? "") { //<-
}
.tag($0)
.buttonStyle(BorderlessButtonStyle())
.frame(width: 48, height: 48, alignment: .center)
.background(RoundedRectangle(cornerRadius: 2)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.4), radius: 2, x: 0, y: 0)
)
}
}
.frame(width: 336.0, height: 48.0, alignment: .leading)
}
}
}
}


Generally in SwiftUI, you should not try to modify the view content by touching each view, but you should define a source of truth for the views and modify the source.

That's interesting. Thanks, OOper. I have to take a close look at what you have done.
Accessing Existing Button with Tag?
 
 
Q