如何删除SwiftUI中“Form”的顶部空格?

9nvpjoqh  于 2023-01-19  发布在  Swift
关注(0)|答案(5)|浏览(200)

我如何在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")
            }
        )
    )
}
zlwx9yxi

zlwx9yxi1#

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操作系统

苹果正在限制appearance黑客攻击,设置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的frameUIKit,则应至少传递最小高度。

注3:

所有的方法都是hacks,苹果试图限制对底层类型(如UITableView)的访问。所以请保持最新状态,并尝试帮助社区。

注4:

通过投票和评论为社区做贡献。这样人们会更有动力去挖掘未知的地方,给我们带来很酷的东西。

注解5:

由于我们使用的是外观代理,任何更改都将应用于应用中的所有TableView。您可以存储原始Appearance的状态-〉应用新样式onAppear,并在需要时恢复原始onDisaper

fjaof16o

fjaof16o2#

设置表头视图在Xcode 12中对我来说已经不起作用了,相反,设置一个负的顶部内容插入似乎也能达到同样的效果。

UITableView.appearance().contentInset.top = -35
ecr0jaav

ecr0jaav3#

如果您使用Introspect,请将其添加到NavigationView中

.introspectTableView {
    $0.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
}
tcbh2hod

tcbh2hod4#

这同样适用:

Form {
   // ...
}._safeAreaInsets(EdgeInsets(top: -18, leading: 0, bottom: 0, trailing: 0))

它也适用于List。但有时它会影响一个大的导航栏标题,在那里它显示为内联,就像你滚动一样。

vvppvyoh

vvppvyoh5#

清除程序将导航栏标题添加到窗体节,然后设置为隐藏

Form {
// add end of form section
}.navigationBarHidden(true).navigationBarTitle("Title") // Form

相关问题