Reputation: 645
I display simple view with two text fields inside a vStack/HStack combination. It leaves a huge gap at the top as shown on the attached image. I tried vStack, it has .leading and .trailing which justifies left or right. How can set specific spacing at the top? code:
struct PlanDetailView: View {
@Environment(\.managedObjectContext) private var viewContext
@Environment(\.dismiss) var dismiss
@Environment(\.presentationMode) var presentationMode
@Binding var chosenPlan: ProviderApiCaller.ProviderData
@State var state: String?
@State var zip: String?
func onAdd(plan: ProviderApiCaller.ProviderData ) {
}
var body: some View {
NavigationView {
VStack {
HStack {
Text(chosenPlan.name!)
}
HStack {
Text(chosenPlan.plans.first!.planUrl)
}
}
}
.navigationTitle("Plan Details")
.toolbar {
// Back button
ToolbarItem(placement: .navigationBarLeading) {
Button(action: { presentationMode.wrappedValue.dismiss() }, label: {
HStack(spacing: 2) {
Image(systemName: "chevron.backward")
.foregroundColor(.black)
Button("Back", action: {
self.presentationMode.wrappedValue.dismiss()
} )
.foregroundColor(.black)
}
})
}
ToolbarItem(placement: .confirmationAction) {
// Button("Save", action: { Task { try? await rI?(nameInput, phoneInput) } })
Button("Save", action: { onAdd(plan: chosenPlan)
} )
.foregroundColor(.blue)
}
}
.navigationViewStyle(StackNavigationViewStyle())
.navigationBarBackButtonHidden(true)
}
Upvotes: 0
Views: 48
Reputation: 9675
For this simple view, you only need to add a Spacer()
in as the last view in the VStack
:
var body: some View {
NavigationView {
VStack {
HStack {
Text(chosenPlan.name!)
}
HStack {
Text(chosenPlan.plans.first!.planUrl)
}
// Place a Spacer() here to push the view to the top
Spacer()
}
}
...
}
Also, you will find that the way you have this view set up, you do not need the HStacks
, so this renders the same as above:
var body: some View {
NavigationView {
VStack {
Text(chosenPlan.name!)
Text(chosenPlan.plans.first!.planUrl)
// Place a Spacer() here to push the view to the top
Spacer()
}
}
...
}
Lastly, you should not be force unwrapping chosenPlan.name
or chosenPlan.plans.first
. You are telling the os to crash your app if those optionals are nil.
var body: some View {
NavigationView {
VStack {
Text(chosenPlan.name ?? "") // nil-coalescing operator (??)
Text(chosenPlan.plans.first?.planUrl ?? "") // nil-coalescing operator (??)
// Place a Spacer() here to push the view to the top
Spacer()
}
}
...
}
You can add whatever default set you want after the nil-coalescing operator (??).
edit:
Based on your comment, I have updated my answer. Rather than setting an absolute position, your would be far better off doing something like this:
var body: some View {
NavigationView {
VStack {
// Set a frame on a Spacer(). In SwiftUI it is better to have a
// view push another view, rather than set an absolute position.
Spacer()
.frame(height: 100)
Text(chosenPlan.name ?? "") // nil-coalescing operator (??)
Text(chosenPlan.plans.first?.planUrl ?? "") // nil-coalescing operator (??)
// Place a Spacer() here to push the view to the top
Spacer()
}
}
...
}
Upvotes: 1