如何将视图的尾部对齐与其父视图的垂直轴对齐?

3
我正在使用SwiftUI制作以下布局。 screenshot 表单标签的“trailing”对齐方式与父视图的中心对齐。类似地,TextFields的“leading”对齐方式也与父视图的中心对齐。 以下是我的代码-
        HStack {
            Spacer()
            VStack {
                HStack {
                    Spacer()
                    Text("Name")
                    TextField("", text: .constant(""))
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .frame(maxWidth: 100)
                }

                HStack {
                    Spacer()
                    Text("Adress")
                    TextField("", text: .constant(""))
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .frame(maxWidth: 100)
                }

                HStack {
                    Spacer()
                    Text("Short Description")
                    TextField("", text: .constant(""))
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .frame(maxWidth: 100)
                }
            }
            .layoutPriority(1)
            Spacer()
        }

导致的结果是

iphone


1
我试了一下你的代码,有两个问题。(1) 你没有发布 BorderedTextFieldstruct,所以我用 TextField 和一个值为10个下划线的代替。(2) 但真正的问题是为什么要添加 layoutPriority(1) 的修饰符?将其注释掉可以解决你的问题。 - user7014451
@dfd 我已经更新了代码和截图,使其更加清晰。移除 layoutPriority(1) 会导致 https://i.imgur.com/IS06CMN.png,因为表单没有优先权来适应间隔器。 - tusharsoni1205
3个回答

0

我想出了一个可能的解决方案,使用GeometryReader可以工作。我仍然希望有更好的方法来做到这一点,但这个方法可行:

      GeometryReader { proxy in
            HStack {
                VStack(spacing: 20) {
                    HStack {
                        Spacer()
                        Text("Name")
                    }

                    HStack {
                        Spacer()
                        Text("Address")
                    }

                    HStack {
                        Spacer()
                        Text("Short Description")
                    }
                }.frame(width: proxy.size.width / 2)

                VStack {
                    HStack {
                        TextField("", text: .constant(""))
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                            .frame(maxWidth: 120)
                        Spacer()
                    }

                    HStack {
                        TextField("", text: .constant(""))
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                            .frame(maxWidth: 120)
                        Spacer()
                    }

                    HStack {
                        TextField("", text: .constant(""))
                            .textFieldStyle(RoundedBorderTextFieldStyle())
                            .frame(maxWidth: 120)
                        Spacer()
                    }
                }.frame(width: proxy.size.width / 2)
            }
        }
  • 将屏幕分成两个等宽的列,使用父元素的宽度
  • 将所有表单标签放在第一列,字段放在第二列
  • 调整表单标签之间的间距,使其与相应的字段对齐

0

好的,我想我已经成功地完成了你所要求的任务。你的解决方案明显是一种所谓的过度工程。在使用GeometryReader之前,请尝试使用更少的视图并尝试不同的配置。这是我的代码(我在ForEach中包装了字段):

字段:

private var fields: some View {
    VStack(alignment: .trailing) {
        ForEach(["Name", "Adress", "Short Description"], id: \.self) { s in
            HStack {
                Text(s)
                TextField("", text: .constant(""))
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .frame(maxWidth: 100)
            }
        }
    }
}

视图:

var body: some View {
    ZStack {
        Spacer()
        fields
            .alignmentGuide(HorizontalAlignment.center) { d in d.width - 100 }
    }
}

这个假设文本字段的宽度保持不变是有效的。对于更复杂的界面,不要避免使用自定义对齐方式,它们非常酷。我建议观看关于此主题的WWDC会议,特别是this one

希望能有所帮助。


0

目前我没有 Xcode,但是为什么你不能把所有的文本放到一个 Vstack 中,然后把 TextField 放到另一个单独的 Vstack 中呢?就像这样:

   HStack {
        HStack {        
            VStack(alignment: .trailing) {
                Spacer()
                Text("Name")
                Text("Adress")
                Text("Short Description")

            }

            VStack{

                BorderedTextField(placeholder: "", text: .constant(""))
                    .frame(maxWidth: 100)
                BorderedTextField(placeholder: "", text: .constant(""))
                    .frame(maxWidth: 100)
                BorderedTextField(placeholder: "", text: .constant(""))
                .frame(maxWidth: 100)
            }
        }
        .layoutPriority(1)
        Spacer()
    }

另外一种可能性是创建自定义对齐方式,WWDC 这里 有一次非常好的讨论。


自定义对齐是一种可能性,但我希望有一种解决方案,使用默认的对齐方式,因为这是在不使用SwiftUI的情况下可以实现的。我们基本上想要将表单标签的尾部对齐方式与父视图的中心指南对齐。 - tusharsoni1205
我也考虑过两个VStack,但由于使用的字体不同,我预计每个单元格的水平对齐可能会出现偏差。 - user7014451

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接