草庐IT

swift - 在 SwiftUI 中制作宽度和高度相同的按钮网格

coder 2023-09-08 原文

我正在尝试使用 SwiftUI 创建一个计算器,我现在正在努力创建按钮网格以水平填充可用空间

现在我只是想让按钮填充高度和宽度相等的 3 x 3 网格

根据 this answer,我可以使用 Spacer() 使它们具有相同的高度但相同的宽度是我现在卡住的地方:

import SwiftUI

struct ContentView : View {
    var body: some View {
        VStack(alignment: .center, spacing: 50) {
            HStack(alignment: .center, spacing: 50) {
                Button(action: {}) {
                    Text("7")
                    Spacer()
                }.background(Color.green)
                Button(action: {}) {
                    Text("8")
                    Spacer()
                }.background(Color.yellow)
                Button(action: {}) {
                    Text("9")
                    Spacer()
                }.background(Color.green)
            }
            HStack(alignment: .center, spacing: 50) {
                Button(action: {}) {
                    Text("4")
                    Spacer()
                }.background(Color.yellow)
                Button(action: {}) {
                    Text("5")
                    Spacer()
                }.background(Color.green)
                Button(action: {}) {
                    Text("6")
                    Spacer()
                }.background(Color.yellow)
            }
            HStack(alignment: .center, spacing: 50) {
                Button(action: {}) {
                    Text("1")
                    Spacer()
                }.background(Color.green)
                Button(action: {}) {
                    Text("2")
                    Spacer()
                }.background(Color.yellow)
                Button(action: {}) {
                    Text("3")
                    Spacer()
                }.background(Color.green)
            }
        }.aspectRatio(contentMode: .fill)
    }
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

这是我当前的输出与我想要的期望输出的示例。首先,我尝试让按钮填充当前区域,稍后我将尝试让 0 按钮填充 2 个单元格。

最佳答案

如何使用GeometryReader (docs here) ?他们将父 View 的维度提供给 subview 。这是基于您已有内容的部分实现:

import SwiftUI

struct ContentView : View {
    var body: some View {
        VStack {
            Text("0")
            NumpadView()
        }
    }
}

struct NumpadView : View {

    let rows: Length = 5
    let columns: Length = 4
    let spacing: Length = 10

    var horizontalEdges: Length {
        return columns - 1
    }

    var verticalEdges: Length {
        return rows - 1
    }

    func getItemWidth(containerWidth: Length) -> Length {
        return (containerWidth - spacing * horizontalEdges) / columns
    }

    func getItemHeight(containerHeight: Length) -> Length {
        return (containerHeight - spacing * verticalEdges) / rows
    }

    var body: some View {
        GeometryReader { geometry in

        VStack(alignment: .center, spacing: self.spacing) {
            HStack(alignment: .center, spacing: self.spacing) {
                Button(action: {}) {
                    Text("7")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.green)
                    }

                Button(action: {}) {
                    Text("8")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.yellow)
                    }

                Button(action: {}) {
                    Text("9")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.green)
                    }
                }

            HStack(alignment: .center, spacing: self.spacing) {
                Button(action: {}) {
                    Text("4")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.yellow)
                }

                Button(action: {}) {
                    Text("5")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.green)
                }

                Button(action: {}) {
                    Text("6")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.yellow)
                }
            }

            HStack(alignment: .center, spacing: self.spacing) {
                Button(action: {}) {
                    Text("1")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.green)
                }

                Button(action: {}) {
                    Text("2")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.yellow)
                }

                Button(action: {}) {
                    Text("3")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.green)
                }
            }

            HStack(alignment: .center, spacing: self.spacing) {
                Button(action: {}) {
                    Text("0")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width) * 2 + self.spacing, height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.yellow)
                }

                Button(action: {}) {
                    Text(".")
                        .frame(width: self.getItemWidth(containerWidth: geometry.size.width), height: self.getItemHeight(containerHeight: geometry.size.height))
                        .background(Color.yellow)
                }
            }

            }.frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

看起来像这样:

关于swift - 在 SwiftUI 中制作宽度和高度相同的按钮网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56658558/

有关swift - 在 SwiftUI 中制作宽度和高度相同的按钮网格的更多相关文章

  1. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  2. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  3. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  4. ruby-on-rails - 优雅的 Rails : multiple routes, 相同的 Controller Action - 2

    让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来

  5. ruby-on-rails - Rails 单选按钮 - 模型中多列的一种选择 - 2

    我希望用户从一个模型的三个选项中选择一个。即我有一个模型视频,可以被评为正面/负面/未知目前我有三列bool值(pos/neg/unknown)。这是处理这种情况的最佳方式吗?为此,表单应该是什么样的?目前我有类似的东西但显然它允许多项选择,而我试图将它限制为只有一个..怎么办? 最佳答案 如果要使用字符串列,让我们说rating。然后在你的表单中:#...#...它只允许一个选择编辑完全相同但使用radio_button_tag: 关于ruby-on-rails-Rails单选按钮-模

  6. ruby-on-rails - 获取并发布相同匹配项的请求 - 2

    在我的路线文件中我有:match'graphs/(:id(/:action))'=>'graphs#(:action)'如果是GET请求(工作)或POST请求(不工作),我想匹配它我知道我可以使用以下方法在资源中声明POST请求:post'/'=>:show,:on=>:member但是我怎样才能为比赛做到这一点呢?谢谢。 最佳答案 如果你同时想要POST和GETmatch'graphs/(:id(/:action))'=>'graphs#(:action)',:via=>[:get,:post]编辑默认值可以设置如下match'g

  7. ruby-on-rails - 多次选择一个随机数,但绝不会两次选择相同的随机数 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:HowdoIgeneratealistofnuniquerandomnumbersinRuby?我想做的事:Random.rand(0..10).timesdoputsRandom.rand(0..10)end但如果随机数已经显示过,则无法再次显示。如何最轻松地做到这一点?

  8. ruby-on-rails - 如何从按钮或链接单击的 View 调用 Rails 方法 - 2

    基本上,我试图在用户单击链接(或按钮或某种类型的交互元素)时执行Rails方法。我试着把它放在View中:但这似乎没有用。它最终只是在用户甚至没有点击“添加”链接的情况下调用该函数。我也用link_to试过了,但也没用。我开始认为没有一种干净的方法可以做到这一点。无论如何,感谢您的帮助。附言。我在ApplicationController中定义了该方法,它是一个辅助方法。 最佳答案 View和Controller是相互独立的。为了使链接在Controller内执行函数调用,您需要对应用程序中的端点执行ajax调用。该路由应调用rub

  9. ruby-on-rails - 如何在 Rails 中添加禁用的提交按钮 - 2

    我在ruby​​表单中有一个提交按钮f.submitbtn_text,class:"btnbtn-onemgt12mgb12",id:"btn_id"我想在不使用任何javascript的情况下通过ruby​​禁用此按钮 最佳答案 添加disabled:true选项。f.submitbtn_text,class:"btnbtn-onemgt12mgb12",id:"btn_id",disabled:true 关于ruby-on-rails-如何在Rails中添加禁用的提交按钮,我们在St

  10. ruby-on-rails - 如何通过 POST 发送多个相同的键/参数? - 2

    如果我必须在一个HTTP请求中发送一堆post参数,所有这些参数都具有相同的名称,我该如何构建要发布的data对象?想象一个带有一些复选框的表单,它们都具有相同的name属性但具有不同的值(如果它们被选中):我想用ruby​​构建它(但它需要根据在表单上选择的内容动态创建):data={"color"=>"red","color"=>"green","color"=>"blue"}然后将数据发送到某个URL:Net::HTTP.post_form(url,data)我无法控制接收端,所以我必须发送它期望接收的参数。怎么办? 最佳答案

随机推荐