Search code examples
swiftformsswiftuispacingsections

SwiftUI Form Label above Text field Section Spacing


I am attempting to create a form in SwiftUI that has the Label above the text input field all the time.

A good example is looking at a contact on an iPhone 12. There are two standalone inputs (among others). Mobile and Notes respectively.

They look and space just how I would like mine.

No matter how I change the following code I always have a large space at the top and the fields themselves have huge spaces in between the Sections.

Form {

    Section() {
        VStack(alignment: .leading) {
            Text("Field1")
            TextField("...", text: $Field1)
        }
        .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
    }
  
    Section() {
            
        VStack(alignment: .leading) {
            Text("Field2")
            TextField("...", text: $Field2)
        }
        .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0))
        
    }
}

If the Form tag here is the issue is it better to remove it and do it all manually. Apple do seem to want you to use the Form tag for cross compatibility. In my case its for iPads and iPhones.


Solution

  • My second answer to my own question. This is what I came up with.

    I decided to go down the route of a separate label above a text input control using the header as the label. This does have a different look.

    This is simply because the original look I was after didn't have the best UI experience.

    It is possible to add extra code but it starts to get far to over complicated.

    Form {
                        
        Section(header: Text("Field1")  // Label
                            .font(.headline)
                            .foregroundColor(.black)
                            // The padding top is larger on the first control to make it stand out more from the navigation bar title.
                            .padding(EdgeInsets(top: 30, leading: 5, bottom: 0, trailing: 0))) {
            TextField("Required", text: $Field1)
        }
        .textCase(nil) // I dont want the label to be all uppercase.
        
        Section(header: Text("Field2")  // Label
                            .font(.headline)
                            .foregroundColor(.black)
                            .padding(EdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 0))) {
            TextField("Required", text: $Field1)
        }
        .textCase(nil)
        
        Section {
            NavigationLink(destination: SomeView()) {
                Text("Next")
                    .padding()
                    .foregroundColor(Color.blue)
            }
        }
    
    }
    .navigationBarTitle("Main Title")