In this iOS tutorial we are going to describe how to use forms in SwiftUI. Forms are a powerful tool, introduced with SwiftUI, enabling mobile developers to build various user forms quickly and efficiently, as opposed to the cumbersome legacy UIKit approach.

Many times while you are creating an app, you want to create some sort of a settings panel or a screen where users could enter various information. In UIKit, this meant using collection views or table views and writing a lot of the boiler plate code over and over again. With SwiftUI, however, you get the ability to create beautiful forms and settings panels using a container called “Forms”.

forms in swiftui

In this article we will create a simple order form in SwiftUI and we will discuss how the behavior of the elements change when you place them inside the Form container.

Let’s start! First launch Xcode and create a new SwiftUI project. Our order form shall have three textfields where the customer will enter name, email address and house address. Then there will be an image of the dish the customer wants to order, with its name, any extra options that the customer may wish to add and lastly a simple picker to increase or decrease the quantity. We will finish the order form with a simple “Order” button at the bottom.

Start by writing the Form container and inside include three TextField elements.

struct ContentView: View {
    @State var name: String = ""
    @State var address: String = ""
    @State var email: String = ""
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Customer Information")) {
                    TextField("Customer Name", text: $name)
                    TextField("Email", text: $email)
                    TextField("Address", text: $address)
                }
            }.navigationBarTitle("Order")
        }
    }
}

I have also wrapped the Form inside a Navigation View, so we will get a navigation bar that says “Order”. As you can see I have also used a Section. This will allow me to divide the Form into different sections and I can provide each section with a header and footer. The header and footer accepts a View, so you can place any custom view or a simple Text view as seen here. Inside this section, I have three TextFields each binder to a @State variable and containing a placeholder text.

Next let’s add an image of the dish being ordered. To do this, we use Image(named: ) to add an image of a burger.

Form {
       Section(header: Text("Customer Information")) {
          TextField("Customer Name", text: $name)
          TextField("Email", text: $email)
          TextField("Address", text: $address)
        }
            
        Image("burger")
           .resizable()
           .frame(width: nil, height: 200)
           .scaledToFit()
 }.navigationBarTitle("Order")

The image is stored in the Assets folder of our project. In order to resize the image, make sure to use the resizable modifier first and then use the frame modifier to provide width and height.

This is how our order form looks like till now.

Now let’s add a new section for our Order preferences. Start by writing a new Section and providing it with a header text of “Order Information”. Inside this section we will add a Text view, a picker view and a stepper view.

@State var burgerOptionTag: Int = 0
@State var quantity: Int = 1
var burgerOption = ["Single Patty", "Double Patty"]
Section(header: Text("Order Information")) {
    Text("Beef Burger")
    HStack {
        Picker("Options", selection: $burgerOptionTag) {
            Text("Single Patty").tag(0)
            Text("Double Patty").tag(1)
        }
        .pickerStyle(MenuPickerStyle())
        Spacer()
        Text(burgerOption[burgerOptionTag])
    }

    Stepper(value: $quantity, in: 1...1000) {
        Text("Quantity: \(quantity)")
    }
}

In this Section, we have added a Text view that shows the name of the dish. After that we have a HStack that houses two elements, a Picker view and a Text view. Now before going any further, I would like to talk about some variables that we have initialized for this section. First being the burgerOptionTag this will be used to store which ever option the user has selected from the Picker view. Then we have a quantity variable that will be used as a binder  with the Stepper view, and lastly we have an array of burger options to be shown in the picker.

The Picker view basically is binder to burgerOptionTag and inside we have listed two views, “Single Patty” and “Double Patty”. Each view has a tag assigned to it. We will use the new MenuPickerStyle which was released in iOS 14. This provides us with a menu to pick the options from.

Also inside this HStack, we have a Text view that shows the option that has been selected using the tag and the burgerOption array.

Next we have a Stepper view. This will help us in incrementing the quantity. Again this also requires a binder so we have a quantity variable bound to it. We can also give a range so that it doesn’t provide us with numbers below 1.

Lastly, we will add a button to finally order the dish. We will use the basic Button components provided to us by SwiftUI.

@State var orderStatus: Bool = false

Button(action: {
    self.orderStatus = true
}, label: {
    HStack {
        Spacer()
        Text(orderStatus ? "Ordered" : "Place Order")
        Spacer()
    }
}).disabled(orderStatus)

Here we have a boolean which we are making true when the button is pressed. When the button is pressed, the Text showing on the button is changed from “Place Order”  to “Ordered” and the button is disabled.

 

Conclusion

This is how easy it is to create a simple order, sign up or settings screen in SwiftUI using Form. As you can notice, building forms in SwiftUI is extremely trivial nowadays, compared to the old legacy approach of UIKit, where developers had to leverage table views or collection views, with a lot of boilerplate code.


Leave a Reply

Your email address will not be published. Required fields are marked *