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

For this simple view, you only need to add a
Spacer()in as the last view in theVStack: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:Lastly, you should not be force unwrapping
chosenPlan.nameorchosenPlan.plans.first. You are telling the os to crash your app if those optionals are nil.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: