【问题标题】:Span two Buttons across HStack in SwiftUI (Big Sur)在 SwiftUI (Big Sur) 中跨 HStack 跨越两个按钮
【发布时间】:2021-07-30 19:33:26
【问题描述】:

我在使用 SwiftUI 为工作表中的两个按钮(取消和确定)正确对齐时遇到问题。

我希望这两个按钮出现在工作表的底部,以便它们两个跨越工作表的整个水平宽度(减去填充)。

我找到了几个答案(例如将maxWidth 设置为.infinityputting the text contend of a button in a separate Text view and surrounding it by Spacers),但它们似乎都不适合我。唯一有效的是by creating my own ButtonStyle。但随后我必须重新创建整个默认 ButtonStyle(默认按钮不同,白天和夜间模式,...)

我现在的代码是:

    var body: some View {
        VStack() {

            ...

            HStack {
                Button("Cancel",action: {
                    isPresented.toggle()
                })
                .frame(minWidth: 0, maxWidth: .infinity)
                .padding()
                .keyboardShortcut(.cancelAction)
                .border(Color.red)
                Button("OK", action: {
                    isPresented.toggle()
                    let newServer = Server(name: name, url: url, port: port, autoConnect: autoConnect)
                    do {
                        try model.add(server: newServer)
                    } catch {
                        print("Could not add server.")
                    }
                })
                .frame(minWidth: 0, maxWidth: .infinity)
                .padding()
                .keyboardShortcut(.defaultAction)
                .border(Color.red)
            }
            .frame(maxWidth: .infinity)
            .padding(.top, 20)
            .border(Color.blue)
        }
        .padding()
        .frame(minWidth: 300, maxWidth: 300)
    }

这会产生以下表格:

我希望两个按钮都填充红色边框包围的区域。

我有点不知道下一步该尝试什么!

【问题讨论】:

标签: macos swiftui macos-big-sur


【解决方案1】:

如红色边框所示,按钮确实会延伸以填充该区域。 要获得图片中的背景灰色,您可以使用以下内容:

.background(Color(UIColor.systemGray4))

作为每个按钮的最后一个修饰符。

【讨论】:

    【解决方案2】:

    默认按钮样式围绕提供的标签内容呈现,因此可能的解决方案是动态计算按钮标签所需的宽度并显式应用它。

    注意:另请参阅我对备用的评论

    使用 Xcode 12.5 / macOS 11.3 准备的演示

    struct ContentView: View {
        @State private var cancelWidth = CGFloat.zero
        @State private var okWidth = CGFloat.zero
    
        var body: some View {
            VStack() {
                Text("Demo here!")
                HStack(spacing: 0) {
                    Button(action: {
                    }) { Text("Cancel").frame(width: cancelWidth) }
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .background(GeometryReader {
                        Color.clear.preference(key: ViewWidthKey.self,
                              value: $0.frame(in: .local).size.width) })
                    .onPreferenceChange(ViewWidthKey.self) { self.cancelWidth = $0 }
                    .padding()
                    .border(Color.red)
                    .keyboardShortcut(.cancelAction)
    
                    Button(action: {
                    }) { Text("OK").frame(width: okWidth) }
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .background(GeometryReader {
                        Color.clear.preference(key: ViewWidthKey.self,
                              value: $0.frame(in: .local).size.width) })
                    .onPreferenceChange(ViewWidthKey.self) { self.okWidth = $0 }
                    .padding()
                    .keyboardShortcut(.defaultAction)
                    .border(Color.red)
                }
                .frame(maxWidth: .infinity)
                .padding(.top, 20)
                .border(Color.blue)
            }
            .padding()
            .frame(minWidth: 300, maxWidth: 300)
        }
    }
    
    struct ViewWidthKey: PreferenceKey {
        typealias Value = CGFloat
        static var defaultValue: CGFloat { 0 }
        static func reduce(value: inout Value, nextValue: () -> Value) {
            value = value + nextValue()
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 2017-11-23
      • 1970-01-01
      • 2020-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      相关资源
      最近更新 更多