如何删除SwiftUI中`Form`的顶部空间?

ake*_*406 11 forms swift swiftui

如何Form在 a 中顶部对齐a NavigationView。我有下面的,当我NaviagationView从身体上取下时,它Form是顶部对齐的。随着NavigationView到位,我在得到之间的间距(添加红色框来显示空间)。我可以.padding(.top, -20)在 Form 上使用,但是虽然这有效,但它会稍微扭曲一些东西。

截屏

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")
            }
        )
    )
} 
Run Code Online (Sandbox Code Playgroud)

Moj*_*ini 27

SwiftUIForm实际上是底层的分组样式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 {
        ,,,
    }
}
Run Code Online (Sandbox Code Playgroud)

iOS 14

Apple 正在限制appearancehack 并且设置tableHeaderView's frame 就是其中之一,因此我们需要通过添加以下步骤进行更多挖掘:

1. 使用约束代替frame

init() {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.heightAnchor.constraint(equalToConstant: 0).isActive = true
    UITableView.appearance().tableHeaderView = view
}
Run Code Online (Sandbox Code Playgroud)

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 
                }
        }

    }
Run Code Online (Sandbox Code Playgroud)

注1:

永远不要对任何数字进行硬编码(例如 -35 表示插入!)。数字因设备、平台和状态等而异。

笔记2:

.zero框架不起作用。如果您frame用于 iOS 13 或UIKit.

注3:

所有方法都是黑客,Apple 正试图限制对诸如UITableView. 因此,请及时了解最新信息并尝试帮助社区。

注4:

通过点赞和评论为社区做出贡献。所以人们会更有动力去未知的地方挖掘并给我们带来很酷的东西。

注5:

由于我们使用的是 Appearance 代理,因此任何更改都将应用于TableView应用程序中的所有s。您可以存储原始状态Appearance-> 应用新样式onAppearonDisaper根据需要恢复原始样式。


Ava*_*rio 13

在 Xcode 12 中设置表头视图不再适用于我。相反,设置负的顶部内容插入似乎可以达到同样的目的。

UITableView.appearance().contentInset.top = -35
Run Code Online (Sandbox Code Playgroud)