【问题标题】:SwiftUI Form Label above Text field Section Spacing文本字段部分间距上方的 SwiftUI 表单标签
【发布时间】:2021-11-07 08:38:12
【问题描述】:

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

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

它们的外观和空间完全符合我的喜好。

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

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 和 iPhone。

【问题讨论】:

  • Form is an as is View 如果您不喜欢它的外观,您必须自己制作一个。
  • "Form is an as is View" ??
  • 接受或保持原样。这是一个预设的外观。
  • 你的回答毫无意义。你是说Form标签中没有办法控制Sections的间距吗?
  • 是的……这是 Apple 提供的特定外观,

标签: swift forms swiftui spacing sections


【解决方案1】:

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

这正是我想要的外观。

看来苹果确实想强迫你“按照他们的方式”去做。

如果您尝试的所有操作都没有一些不必要的连锁效应,就很难更改表单 view 格式。

我同意一些 cmets 的观点,即这看起来确实正确,但它没有最好的 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")

【讨论】:

  • 您可能想要添加有关您所做更改的一些详细信息。答案是给后代的,以便其他人可以跟随并理解是什么以及为什么。本质上,您只是将它们分组到同一个部分中,而不是单独的部分。此外,从可用性的角度来看,用户必须点击TextField(),而不仅仅是VStack(),才能真正输入数据。这可能接近您想要的外观,但可能不太适合用户。 YMMV。
  • @Yrb 很高兴看到你的回答。
  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
【解决方案2】:

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

我决定使用标题作为标签在文本输入控件上方使用单独标签的路线。这确实有不同的外观。

这仅仅是因为我追求的原始外观没有最好的 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")

【讨论】:

    【解决方案3】:

    正如我在 cmets 中所说,您也可以将字段标题作为 Section 标头。此外,这是您的 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 设置为相同)。接下来是场地周围没有填充物。最后一个允许系统选择您的填充。

    【讨论】:

    • 虽然这并没有创造出我想要的外观,但我最终还是做了类似的事情,因为让整个控件检测到触摸太复杂了,我同意这不是最好的用户体验。我要编辑我原来的答案
    • 在另一个小笔记中我发现这个方法不需要VStack。
    • 是的,你是对的。没有第二个视图,VStack 什么也不做。我将编辑我的答案。我更专注于部分标题。
    • 经过反思,我现在实际上更喜欢这种外观而不是我原来的外观。使点击位置更加清晰。
    猜你喜欢
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 2017-05-03
    相关资源
    最近更新 更多