与SwiftUI相等的子视图宽度

时间:2019-06-16 16:03:11

标签: watch-os swiftui

我正在尝试使用SwiftUI构建一个简单的watchOS UI,并在按钮上方并排放置两条信息。

我希望每一面(在VStack中表示为HStack)占可用宽度的一半(因此在黄色父视图中是50/50的均分)在下面的示例中, | 字符位于按钮的中心。

我希望每个文本的 Short Longer !!! 居于每边50%的中心。

我从这段代码开始,将元素放置到位并显示某些不同堆栈的边界:

var body: some View {
    VStack {
        HStack {

            VStack {
                Text("Short").font(.body)
            }
                .background(Color.green)

            VStack {
                Text("Longer!!!").font(.body)
            }
                .background(Color.blue)

        }
            .frame(minWidth: 0, maxWidth: .infinity)
            .background(Color.yellow)
        Button (action: doSomething) {
            Text("|")
        }
    }
}

哪个给了我这个结果: starting point

然后,当将每个VStack并排设置为可用宽度的50%时,我陷入了困境。我认为应该为每个.relativeWidth(0.5)添加VStack,按照我的理解,应该使每个VStack为其父视图的宽度的一半(HStack,黄色背景):

var body: some View {
    VStack {
        HStack {

            VStack {
                Text("Short").font(.body)
            }
                .relativeWidth(0.5)
                .background(Color.green)

            VStack {
                Text("Longer!!!").font(.body)
            }
                .relativeWidth(0.5)
                .background(Color.blue)

        }
            .frame(minWidth: 0, maxWidth: .infinity)
            .background(Color.yellow)
        Button (action: doSomething) {
            Text("|")
        }
    }
}

但这是我得到的结果: unexpected widths

如何通过SwiftUI获得我想要的行为?


更新:在进一步阅读了SwiftUI文档之后,我看到the example here设置了一个框架,然后定义了与该框架相比的相对宽度,所以也许我不应该这样做以这种方式使用relativeWidth

通过以下代码,我离想要的东西更近了:

var body: some View {
    VStack {
        HStack {

            VStack {
                Text("Short").font(.body)
            }
                .frame(minWidth: 0, maxWidth: .infinity)
                .background(Color.green)

            VStack {
                Text("Longer!!!").font(.body)
            }
                .frame(minWidth: 0, maxWidth: .infinity)
                .background(Color.blue)

        }
            .frame(minWidth: 0, maxWidth: .infinity)
            .background(Color.yellow)
        Button (action: doSomething) {
            Text("|")
        }
    }
}

产生以下结果:

closer to expected result

现在,我试图找出是什么原因在两个VStack之间的中间产生了额外的空间。到目前为止,尝试摆脱填充并忽略安全区域的尝试似乎并未对其产生影响。

3 个答案:

答案 0 :(得分:5)

我仍然对应该何时使用relativeWidth以及如何使用relativeWidth感到困惑,但是我无需使用它就能实现我想要的愿望。 (编辑2019年7月18日::根据iOS 13 Beta 4发行说明,HStack已被弃用)

在对我的问题的最后一次更新中,我在两边之间都有一些额外的间距,并且意识到这是var body: some View { VStack { HStack(spacing: 0) { VStack { Text("Short").font(.body) } .frame(minWidth: 0, maxWidth: .infinity) .background(Color.green) VStack { Text("Longer!!!").font(.body) } .frame(minWidth: 0, maxWidth: .infinity) .background(Color.blue) } .frame(minWidth: 0, maxWidth: .infinity) .background(Color.yellow) Button (action: doSomething) { Text("|") } } } 上的默认间距,并且我能够通过将其间距设置为0来删除它。这是最终的代码和结果:

"Action": "UPSERT",
                "ResourceRecordSet": {
                    "Name": "hello.example.com.",
                    "Type": "CNAME",
                    "TTL": 60,
                    "Weight": 0,
                    "SetIdentifier": "green",
                    "ResourceRecords": [{ "Value": "https://xxxxxxxxxxxxxxxxxxx.amazonaws.com/v1" }]
                    }

结果如下: final result without spacing

答案 1 :(得分:0)

键是 fixedSize

 VStack {
        Text("Short Text")
            .frame(maxWidth: .infinity)
            .background(Color.red)
        Text("Very very very long Text")
            .frame(maxWidth: .infinity)
            .background(Color.yellow)
    }
    .frame(maxWidth: .infinity)
    .fixedSize(horizontal: true, vertical: true)

结果如下。

Result

答案 2 :(得分:-1)

您已将 backgroundHStack 设置为黄色,并且 HStack 具有一些默认的子视图间间距。通过在 spacing: 0 中添加 HStack 将解决问题,请参阅下面的更新代码。

var body: some View {
    VStack {
        HStack(spacing: 0) { // Set spacing here
            VStack {
                Text("Short").font(.body)
            }
                .frame(minWidth: 0, maxWidth: .infinity)
                .background(Color.green)

            VStack {
                Text("Longer!!!").font(.body)
            }
                .frame(minWidth: 0, maxWidth: .infinity)
                .background(Color.blue)

        }
            .frame(minWidth: 0, maxWidth: .infinity)
            .background(Color.yellow)
        Button (action: doSomething) {
            Text("|")
        }
    }
}