skip to Main Content

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.

3

Answers


  1. 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

    Login or Signup to reply.
  2. 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)
            }
        }
    }
    
    Login or Signup to reply.
  3. 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)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search