文本字段上方的 SwiftUI 表单标签部分间距

SwiftUI Form Label above Text field Section Spacing

我正在尝试在 SwiftUI 中创建一个表单,该表单的标签始终位于文本输入字段上方。

一个很好的例子是查看 iPhone12 上的联系人。有两个独立的输入(以及其他)。分别是手机和笔记。

它们看起来 space 正是我想要的样子。

无论我如何更改以下代码,我总是在顶部有一个大 space,并且字段本身在各部分之间有巨大的 space。

Form {

    Section() {
        VStack(alignment: .leading) {
            Text("Field1")
            TextField("...", text: $Field1)
        }
        .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
    }
  
    Section() {
            
        VStack(alignment: .leading) {
            Text("Field2")
            TextField("...", text: $Field2)
        }
        .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
        
    }
}

如果这里的表单标签是问题所在,最好将其删除并全部手动完成。 Apple 似乎确实希望您使用 Form 标签来实现交叉兼容性。就我而言,它适用于 iPad 和 iPhones。

我对自己问题的第一个回答。这是我想到的(但决定不使用)。

这正是我想要的外观。

看来 Apple 真的很想强迫你按“他们的方式”去做。

很难更改表格 视图 格式,除非您尝试的所有内容都会产生一些不必要的连锁反应。

我同意一些评论,这看起来确实正确,但没有最好的 UI 体验。

Form {
            
   Section() {

        VStack(alignment: .leading) {
            Text("Field1")
                .font(.headline)
            TextField("Required", text: $Field1)
        }
        .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))

        VStack(alignment: .leading) {
            Text("Field2")
                .font(.headline)
            TextField("Optional", text: $Field2)
        }
        .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))

    }
    
    Section {
        NavigationLink(destination: SomeView()) {
            Text("Next")
                .padding()
                .foregroundColor(Color.blue)
        }
    }

}
.navigationBarTitle("Main Title")

正如我在评论中所说,您也可以将字段标题作为 Section header。另外,这是你的UI,按照你的意愿去做。我对它的唯一评论是在设计它时要考虑可用性。您的回答为用户提供了一个看起来很大的目标,但实际上只有那个大小的一半。我并不是说这对您的应用来说是错误的,只是您应该考虑一下。

    Form {
        
        Section(header: Text("Field1") ) {
            TextField("Required", text: $Field1)
                // With padding that is equivalent to your padding.
                .padding(.vertical, 10)
            // .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
        }
        
        Section(header: Text("Field2") ) {
            TextField("Optional", text: $Field2)
            // Without padding...
        }
        
        Section(header: Text("Field3") ) {
            TextField("Optional", text: $Field2)
                // With padding that is determined by the system.
                .padding(.vertical)
        }
    }

显然,这给了你不一样的感觉。您会注意到,我给了您三种不同的 .padding() 外观。一个是你的,而不是使用具有相同常量的 .vertical(设置 .top.bottom 相同)。接下来是在字段周围没有填充。最后允许系统选择你的填充。

我对自己问题的第二个回答。这是我想出来的。

我决定使用 header 作为标签沿着文本输入控件上方的单独标签的路线走下去。这确实有不同的外观。

这仅仅是因为我想要的原始外观没有最好的 UI 体验。

可以添加额外的代码,但它开始变得过于复杂。

Form {
                    
    Section(header: Text("Field1")  // Label
                        .font(.headline)
                        .foregroundColor(.black)
                        // The padding top is larger on the first control to make it stand out more from the navigation bar title.
                        .padding(EdgeInsets(top: 30, leading: 5, bottom: 0, trailing: 0))) {
        TextField("Required", text: $Field1)
    }
    .textCase(nil) // I dont want the label to be all uppercase.
    
    Section(header: Text("Field2")  // Label
                        .font(.headline)
                        .foregroundColor(.black)
                        .padding(EdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 0))) {
        TextField("Required", text: $Field1)
    }
    .textCase(nil)
    
    Section {
        NavigationLink(destination: SomeView()) {
            Text("Next")
                .padding()
                .foregroundColor(Color.blue)
        }
    }

}
.navigationBarTitle("Main Title")