simsab
simsab

Reputation: 131

How to force Picker selection text to fit in 1 line?

With some items of my picker, the text of the selected item takes 2 lines, how can I avoid this ?

Image of the Picker with the text on 2 lines

There is my code :

struct PickerTestView: View {
    
    @AppStorage("firstNotificationSelection") var firstNotificationSelection: String = (UserDefaults.standard.string(forKey: "firstNotificationSelection")) ?? "None"
    @AppStorage("secondNotificationSelection") var secondNotificationSelection: String = (UserDefaults.standard.string(forKey: "secondNotificationSelection")) ?? "None"

    let notificationChoices: [String] = ["None", "At time of match", "5 minutes before...", "10 minutes before...", "30 minutes before...", "1 hour before...", "2 hours before..."]
    
    var body: some View {
        NavigationStack {
            Form {
                Section {
                    Picker(selection: $firstNotificationSelection) {
                        ForEach(notificationChoices, id: \.self) { choice in
                            Text(choice)
                        }
                    } label: {
                        Text("Alert")
                    }
                    if firstNotificationSelection != "None" {
                        Picker(selection: $secondNotificationSelection) {
                            ForEach(notificationChoices, id: \.self) { choice in
                                Text(choice)
                            }
                        } label: {
                            Text("Second alert")
                        }
                    }
                }
            }
            .navigationTitle("Notifications")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

I tried with the modifier .lineLimit(1) and to fix the frame of the Picker but it has no effect.

Upvotes: 5

Views: 1080

Answers (3)

ctigelaar
ctigelaar

Reputation: 73

When using .pickerStyle(.navigationLink) it works. The Picker will navigate to it's own view to display the options, but when it returns to the form it shows the selection on 1 line. Worked for me.

In your case this should work I think:

Picker("Alert", selection: $firstNotificationSelection) {
  ForEach(notificationChoices, id: \.self) { choice in
    Text(choice)
  }
}.pickerStyle(.navigationLink)

Upvotes: 2

Fault
Fault

Reputation: 1339

you have more control if you wrap your picker inside a Menu

Menu {
    Picker(selection: $firstNotificationSelection, label: EmptyView(), content: {
        ForEach(notificationChoices, id: \.self) { choice in
            Text(choice)
        }
    })
} label: {
    Text(firstNotificationSelection)
}

enter image description here

or, in the full context of your example, it would look like this

struct PickerTestView: View {
    
    @AppStorage("firstNotificationSelection") var firstNotificationSelection: String = (UserDefaults.standard.string(forKey: "firstNotificationSelection")) ?? "None"
    @AppStorage("secondNotificationSelection") var secondNotificationSelection: String = (UserDefaults.standard.string(forKey: "secondNotificationSelection")) ?? "None"

    let notificationChoices: [String] = ["None", "At time of match", "5 minutes before...", "10 minutes before...", "30 minutes before...", "1 hour before...", "2 hours before..."]
    
    var body: some View {
        NavigationStack {
            Form {
                Section {
                    HStack {
                        Text("Alert")
                        
                        Spacer()
                        
                        Menu {
                            Picker(selection: $firstNotificationSelection, label: EmptyView(), content: {
                                ForEach(notificationChoices, id: \.self) { choice in
                                    Text(choice)
                                }
                            })
                        } label: {
                            Text(firstNotificationSelection)
                        }
                    }
                    
                    if firstNotificationSelection != "None" {
                        HStack {
                            Text("Second Alert")
                            
                            Spacer()
                            
                            Menu {
                                Picker(selection: $secondNotificationSelection, label: EmptyView(), content: {
                                    ForEach(notificationChoices, id: \.self) { choice in
                                        Text(choice)
                                    }
                                })
                            } label: {
                                Text(secondNotificationSelection)
                            }
                        }
                    }
                }
            }
            .navigationTitle("Notifications")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

Upvotes: 4

easydev991
easydev991

Reputation: 311

As of today (feb 2023) the default SwiftUI picker does not have an option to change the number of lines for the selected value text

Upvotes: -1

Related Questions