How do I top align a Form
within a NavigationView
. I have the below, when I remove NaviagationView
from the body, the Form
is top aligned. With NavigationView
in place, I get spacing in between(red box added to show space). I can use .padding(.top, -20)
on the Form but while this works it skews things slightly.
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")
}
)
)
}
SwiftUI lets us set individual padding around views using the padding() modifier, causing views to be placed further away from their neighbors. SPONSORED Build Chat messaging quickly with Stream Chat.
SwiftUI gives us a dedicated view type for this purpose, called Form . Forms are scrolling lists of static controls like text and images, but can also include user interactive controls like text fields, toggle switches, buttons, and more.
SwiftUI Form
is actually a grouped style UITableView
under the hood and that is default tableHeaderView
. So you can remove it like this:
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 {
,,,
}
}
Apple is limiting the appearance
hack and setting the tableHeaderView
's frame is one of them so we need to dig more around by adding these steps:
frame
:init() {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.heightAnchor.constraint(equalToConstant: 0).isActive = true
UITableView.appearance().tableHeaderView = view
}
The constraint is added but it needs a reload. SwiftUI does not allow you to reload a list manually. So we need to add a dummy view and a dummy state
to trick it:
@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
}
}
}
Try never hard-code any numbers (like -35 for inset!). Numbers vary on different devices and platforms and states and etc.
.zero
frame is not working. You should pass at least a minimum height if you use frame
for iOS 13 or UIKit
.
All methods are hacks and Apple is trying to restrict access to underlying types like UITableView
. So stay up to date and try to help the community.
Contribute to the community by upvoting and commenting. So people will be more motivated to dig in unknown places and bring us cool stuff.
Since we are using the Appearance proxy, any change will be applied to all TableView
s in the app. You can store the state of the original Appearance
-> apply the new style onAppear
and restore the original onDisaper
if needed.
if you use Introspect add this to your NavigationView
.introspectTableView {
$0.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: Double.leastNonzeroMagnitude))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With