Reputation: 4308
I want to define a layout like this:
How can I let the Buttons grab all the available width, also when the user resizes the Window.
In the upper part three rows of equal width, in the lower part one row with max. width
struct TEST: View {
let columns = [
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible())
]
let data = ["1 Text ...",
"2 longer Text ...",
"3 Text ...",
"4 Text/FA/Tra ...",
"5 Text ...",
"6 Text ...",
"7 Text ...",
"8 Text ...",
"9 Text ...",
]
var body: some View {
VStack (alignment: .leading ){
LazyVGrid(columns: columns) {
ForEach(data, id: \.self) { item in
Button(action: {print("")}){
Text(item).background(Color.green)
}
.background(Color.yellow)
}
}
.padding(.horizontal)
}
Button("even longer Text"){print("x")}
Button("even longer Text"){print("x")}
Button("even longer Text"){print("x")}
}
}
Upvotes: 1
Views: 741
Reputation: 1
You can use the frame(maxWidth: .infinity)
command. However, the trick is to apply the width style to the label of the button itself as opposed to the actual button declaration.
Here is a sample code on how to do this in Swift UI
Button {
doSomething()
} label: {
Text("Click me").frame(maxWidth: .infinity)
}
.buttonStyle(.borderedProminent)
Upvotes: 0
Reputation: 54661
You can use .frame(maxWidth: .infinity)
:
Button("even longer Text") {
print("x")
}
.frame(maxWidth: .infinity)
EDIT
Here is a more detailed example:
var body: some View {
VStack(alignment: .leading) {
LazyVGrid(columns: columns) {
ForEach(data, id: \.self) { item in
Button(action: { print("") }) {
Text(item)
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
.background(Color.yellow)
}
}
.padding(.horizontal)
.background(Color.blue)
}
Button(action: { print("x") }) {
Text("even longer Text")
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
.background(Color.purple)
...
}
I added colors, so you can see that buttons are aligned properly.
Tested with Xcode 12.3, macOS 11.1
Upvotes: 1
Reputation: 4308
Found a solution:
struct TEST: View {
let columns = [
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible())
]
let data = ["1 Text ...",
"2 longer Text ...",
"3 Text ...",
"4 Text/FA/Tra",
"5 Text ...",
"6 Text ...",
"7 Text ...",
"8 Text ...",
"9 Text ...",
]
var body: some View {
VStack (alignment: .leading ){
LazyVGrid(columns: columns) {
ForEach(data, id: \.self) { item in
ExpandingButton(s: item){print("pressed")}
}
}
.padding(.horizontal)
}
ExpandingButton(s: "Hogo"){print("hogo")}
ExpandingButton(s: "Hogo"){print("hogo")}
ExpandingButton(s: "Hogo"){print("hogo")}
}
}
struct ExpandingButton: View {
var s : String
var action: ()->Void
var body: some View {
HStack (alignment: .top){
Spacer()
Text(s)
.padding(4)
Spacer()
}
.background(Color.gray)
.cornerRadius(4)
.onTapGesture {action()}
}
}
Upvotes: 0