如何在 SwiftUI 中删除“表单”的顶部空间?
Posted
技术标签:
【中文标题】如何在 SwiftUI 中删除“表单”的顶部空间?【英文标题】:How to remove top space of `Form` in SwiftUI? 【发布时间】:2019-11-03 14:43:47 【问题描述】:如何在NavigationView
中对齐Form
。我有以下内容,当我从正文中删除 NaviagationView
时,Form
是顶部对齐的。使用NavigationView
,我在两者之间获得了间距(添加了红色框以显示空间)。我可以在表单上使用.padding(.top, -20)
,但是虽然这可行,但它会稍微倾斜。
NavigationView
Form
VStack
HStack
Text("Name:").underline().font(.headline)
TextField("Name", text: $routine.name)
roundPicker()
TimeSelectionView(stateName: "A", stateDuration: "0:30", stateBackground: "#df405a")
TimeSelectionView(stateName: "B", stateDuration: "1:30", stateBackground: "#4ea1d3")
TimeSelectionView(stateName: "C", stateDuration: "3:00", stateBackground: "#4f953b")
.navigationBarTitle("Create", displayMode: .inline)
.navigationBarItems(trailing:
Button(action:
//Save Routine
self.routine.rounds = self.roundsArray[self.rounds]
print("Workout Name: \(self.routine.name)")
print("Workout Rounds: \(self.routine.rounds)")
, label:
Text("Save")
)
)
【问题讨论】:
将.listStyle(GroupedListStyle())
应用于List
视图时也会出现差距,并且接受的答案也适用于这种情况。
【参考方案1】:
SwiftUI Form
实际上是一个分组样式 UITableView
在底层,这是默认的 tableHeaderView
。所以你可以像这样删除它:
ios 13
struct ContentView: View
init() // this can be done in `onAppear` modifier if you need to restore the appereance later on `onDisappear`
UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
var body: some View
,,,
iOS 14
Apple 正在限制 appearance
hack,设置 tableHeaderView
的框架就是其中之一,因此我们需要通过添加以下步骤来进一步挖掘:
1。使用约束代替frame
:
init()
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.heightAnchor.constraint(equalToConstant: 0).isActive = true
UITableView.appearance().tableHeaderView = view
2。强制重新加载表:
已添加约束,但需要重新加载。 SwiftUI 不允许您手动重新加载列表。所以我们需要添加一个虚拟视图和一个虚拟state
来欺骗它:
@State var loaded = false // need for stay update
,,,
List
if loaded
Text("Actual content of the list")
else
Text("Dummy content. Not important")
.onAppear
loaded = true // need for instatnt force update
注1:
尽量不要对任何数字进行硬编码(例如插入 -35!)。数字在不同的设备、平台和状态等方面有所不同。
注2:
.zero
框架不工作。如果你在 iOS 13 上使用 frame
或 UIKit
,你应该至少通过一个最小高度。
注3:
所有方法都是hacks,Apple 正试图限制对UITableView
等底层类型的访问。因此,请及时了解最新情况并尝试帮助社区。p>
注4:
通过点赞和评论为社区做出贡献。所以人们会更有动力去未知的地方挖掘,给我们带来很酷的东西。
注5:
由于我们使用外观代理,任何更改都将应用于应用程序中的所有TableView
s。您可以存储原始Appearance
的状态 -> 应用新样式onAppear
并在需要时恢复原始onDisaper
。
【讨论】:
谢谢!就是这样! 有什么办法不一定在整个应用程序范围内执行此操作,而仅针对表单? 是的。在 Appear() 上做 这也适用于 iPad 上带有 SidebarStyle() 的列表。甚至在 Xcode12 中为 List 工作,没有尝试过 Form。 @MojtabaHosseini 很久以前,我知道,但你的建议仍然使它成为全球性的,只是从这段代码第一次执行 onAppear 开始。【参考方案2】:在 Xcode 12 中设置表头视图不再适合我。相反,设置负顶部内容插入似乎可以达到同样的效果。
UITableView.appearance().contentInset.top = -35
【讨论】:
这是 Xcode 12 的正确答案。谢谢!!【参考方案3】:如果您使用Introspect,请将其添加到您的 NavigationView
.introspectTableView
$0.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
【讨论】:
【参考方案4】:Cleaner 在表单部分添加导航栏标题,然后设置隐藏
Form
// add end of form section
.navigationBarHidden(true).navigationBarTitle("Title") // Form
【讨论】:
这会删除导航栏,而不是第一个表单元素上方的空间。以上是关于如何在 SwiftUI 中删除“表单”的顶部空间?的主要内容,如果未能解决你的问题,请参考以下文章