Helping creating a drop down menu

Hello, I was wondering how do i create a drop down menu for my app, like this oneimage

Hey @kiki21a Chris teaches us how to do this in the iOS Foundations course, you use something called a Picker with the .pickerStyle(MenuPickerStyle()) modifier. In particular, module four lesson nine goes over the different Picker styles that might interest you.

Here’s the code to produce the drop down menu, you desire:

// Define State properties to save the selected options, 
// Define the menu options to choose from in the dropdown
@State var location = ["Los Angeles", "Queens", "Manhattan", "DC", "Miami", "Chicago", "Detroit"]
// Save the selected index, so we can use it later to show as a Text element the location chosen by the user
@State var locationIndex = 0

HStack {

  Picker("Select Location: ", selection: $locationIndex) {
  // Loop through each element in our location list with a Text view
    ForEach(0..<location.count) { index in
      Text("\(location[index])")
    }
  }
  .pickerStyle(MenuPickerStyle())

  // Display the chosen style on the screen here
  Text("\(location[locationIndex])")              
}

I did this Module 4 Lesson 9 Challenge that shows exactly how to use the different Pickers’ styles. See my repo here for a screenshot of how an app looks implementing all these, then dive into the ContentView to see the code that created it.

Thank you!

1 Like

Hey you’re welcome :slight_smile: let me know, if you run into any more difficulties getting it to work!

Cheers,
Andrew

When I was setting up the picker, I ran into an error it says “Closure containing a declaration cannot be used with result builder ‘ViewBuilder’”, how do I fix this?

And I have another question not related to the picker, when I press run to run the simulator, it’s showing an older version of my app not the one I’m working on right now

import SwiftUI

struct EventView: View {
    
    @State var selectedIndex = 1
    
    var body: some View {
        
        VStack {
        
        Picker("Seect Specail Event", selection: $selectedIndex) {
            Text("Birthday") .tag(1)
            Text("Anniversary") .tag(2)
            Text("Baptism") .tag(3)
            
                .pickerStyle(MenuPickerStyle())
            
            Text("You've selcted: /(selectedIndex)")
        }
}

        struct EventView_Previews: PreviewProvider {
    static var previews: some View {
        EventView()
    }
}
}
}
```![Screen Shot 2022-02-09 at 9.19.32 AM|690x431](upload://qzaNVFRFeKlm7vPdpbZjnP1lHyC.png)

You have your EventView_Previews struct nested inside your EventView struct.

1 Like

You’re missing some }. Add one after Text("Baptism").tag(3).

The way you wrote @RedFox1’s code puts the Preview Struct in the same struct as your view, which is causing the error. It’s most likely showing an older version of your app because of the error. Xcode will only update the Simulator with a newer version of your app if it doesn’t detect any errors in your code.

This issue might be better visualized by selecting all the code in that file and going to Editor > Structure > Re-Indent in Xcode.

Side Note:
Text("You've selected: /(selectedIndex)") should be written as Text("You've selected: \(selectedIndex)"). This way, it’ll access the selectedIndex property.

I did all that and there are no errors, but it’s still showing an older/deleted version of the app.
Here are two screenshots: 1st one is of the screen that is supposed to show and the 2nd one is the one that is actually showing on the simulator!


Also how do I make a screen where the person will put information in like their name and birthday
Ex:
Name:______
Birthday:_____

One way to do it would be a Form. You don’t necessarily need a Form to do this though. It would look something like this:

// State variables to store the values of the TextField and DatePicker
@State var name = ""
@State var birthday = Date()

var body: some View {
  Form {
    // Name
    Section(header: Text("Name")) {
      TextField("Name", $name)
    }
  
    // Birthday
    Section(header: Text("Birthday")) {
      DatePicker("Birthday", selection: $birthday, in: ...Date(), displayedComponents: .date)
      // in: ...Date() refers to the range the user can select from
      // It wouldn't make sense if the user could select a date that hasn't happened yet
      // By default a DatePicker will let the user pick a time and date
      // displayedComponents: .date, restricts it to date selection only
    }
  }
}

How would i add a message area(a field where you can put a personal messsgae in)

You could use another TextField.

If you want more of a multiline textbox something like this should work:
https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-multi-line-editable-text-with-texteditor

When I tried to that but I got a few errors

What error(s) did you get? Can You post your code?

This is the error code I got, I had to chance a couple of things in the app "Closure containing a declaration cannot be used with result builder ‘ViewBuilder’ " and “Expected pattern”

 import SwiftUI

struct MessageView: View {
    var body: some View {
        // State variables to store the values of the TextField and DatePicker
        @State var name = ""
        @State var "Special Day Date" = Date()

        var body: some View {
          Form {
            // Name
            Section(header: Text("Name")) {
              TextField("Name", $name)
            }
          
            // Birthday
            Section(header: Text("Birthday")) {
              DatePicker("Special Day Date", selection: $date, in: ...Date(), displayedComponents: .date)
              // in: ...Date() refers to the range the user can select from
              // It wouldn't make sense if the user could select a date that hasn't happened yet
              // By default a DatePicker will let the user pick a time and date
              // displayedComponents: .date, restricts it to date selection only
            }
          }
        }
    }
}

You have got 2 declarations of var Body: some View. There should only be one.

Your @State var "Special Day Date" = Date() is not in the correct format. Your declaration should be something like this:

@State var birthday = Date()

TextField should be specified like this:

TextField("Enter Name", text: $name)

With the declaration of the State variable for the birthday set up correctly your DatePicker will now need to be corrected to use that variable as the binding in selection.

DatePicker("Special Day Date", selection: $birthday, in: ...Date(), displayedComponents: .date)

The overall code could look like this:

struct MessageView: View {
    // State variables to store the values of the TextField and DatePicker
    @State var name = ""
    @State var birthday = Date()

    var body: some View {
        Form {
            // Name
            Section(header: Text("Name")) {
                TextField("Enter Name", text: $name)
            }

            // Birthday
            Section(header: Text("Birthday")) {
                DatePicker("Special Day Date", selection: $birthday, in: ...Date(), displayedComponents: .date)
                // in: ...Date() refers to the range the user can select from
                // It wouldn't make sense if the user could select a date that hasn't happened yet
                // By default a DatePicker will let the user pick a time and date
                // displayedComponents: .date, restricts it to date selection only
            }
        }
    }
}
1 Like