I have just begun learning Swift (and even newer at Swift UI!) so apologies if this is a newbie error.
I am trying to write a very simple programme where a user chooses someone's name from a picker and then sees text below that displays a greeting for that person.
But, the bound var chosenPerson does not update when a new value is picked using the picker. This means that instead of showing a greeting like "Hello Harry", "Hello no-one" is shown even when I've picked a person.
struct ContentView: View {
var people = ["Harry", "Hermione", "Ron"]
@State var chosenPerson: String? = nil
    var body: some View {
        NavigationView {
            Form {
        Section {
    Picker("Choose your favourite", selection: $chosenPerson) {
        ForEach ((0..<people.count), id: \.self) { person in
            Text(self.people[person])
            }
        }
        }
        Section{
            Text("Hello \(chosenPerson ?? "no-one")")
        }
        }
    }
   }
}
(I have included one or two pieces of the original formatting in case this is making a difference)
I've had a look at this question, it seemed like it might be a similar problem but adding .tag(person) to Text(self.people[person])did not solve my issue. 
How can I get the greeting to show the picked person's name?
Bind to the index, not to the string. Using the picker, you are not doing anything that would ever change the string! What changes when a picker changes is the selected index.
struct ContentView: View {
    var people = ["Harry", "Hermione", "Ron"]
    @State var chosenPerson = 0
    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker("Choose your favourite", selection: $chosenPerson) {
                        ForEach(0..<people.count) { person in
                            Text(self.people[person])
                        }
                    }
                }
                Section {
                    Text("Hello \(people[chosenPerson])")
                }
            }
        }
    }
}

The accepted answer is right if you are using simple arrays, but It was not working for me because I was using an array of custom model structs with and id defined as string, and in this situation the selection must be of the same type as this id. Example:
struct CustomModel: Codable, Identifiable, Hashable{
var id: String // <- ID of type string
var name: String
var imageUrl: String
And then, when you are going to use the picker:
struct UsingView: View {
@State private var chosenCustomModel: String = "" //<- String as ID
@State private var models: [CustomModel] = []
var body: some View {
 
        VStack{
            
                Picker("Picker", selection: $chosenCustomModel){
                        ForEach(models){ model in
                            Text(model.name)
                                .foregroundColor(.blue)
                        }
                    }
                }
Hope it helps somebody.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With