让我们在 MacOS AppKit 上的 SwiftUI 中使用所有可用宽度的按钮

问题描述

我想定义这样的布局:

enter image description here

如何让按钮获取所有可用的宽度,也可以在用户调整窗口大小时。
上部三排等宽,下部一排最大。宽度

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")}
  }
}

解决方法

您可以使用.frame(maxWidth: .infinity)

Button("even longer Text") { 
    print("x") 
}
.frame(maxWidth: .infinity)

编辑

这是一个更详细的例子:

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)
    ...
}

我添加了颜色,因此您可以看到按钮已正确对齐。

enter image description here

使用 Xcode 12.3、macOS 11.1 测试

,

找到了解决办法:

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()}
  }
}