Home > Enterprise >  SwiftUI Picker iOS 16 not filling available space
SwiftUI Picker iOS 16 not filling available space

Time:12-30

I am using the following code (example) to render a SwiftUI Picker on iOS:

let strings: [String] = ["short", "very, ver long string"]
@State var selectedString: String = ""
Form {
   Picker("Method", selection: $selectedString) {
      ForEach(strings, id: \.self) { string in
         Text(string)
      }
   }
}

In iOS 16 the design of the menu style picker has changed (it now includes 2 small chevrons), which is all good, except it no longer fills the available width (as it did on iOS 15). This results in longer strings flowing onto multiple lines even when this isn't neccessary.

Short String (all fine):

iOS Simulator, showing a short string on a single line in a SwiftUI Picker

Long String (not so good):

iOS Simulator, showing a longer string on a two lines in a SwiftUI Picker

I have tried .fixedSize(), which works to some extend but if the string does in fact need to be on two lines this forces the label to be squished. If I add a background to the Picker, it is clear that it only fills around 1/3 of the available space.

Does anyone have any suggestions?

CodePudding user response:

Separate the label from the Picker and wrap it in a HStack.

Form {
    HStack {
        // the new label text
        Text("Method")
            .fixedSize() // give other views in HStack space to grow
        // push the external label and Picker to the leading and trailing view edges
        Spacer()
        Picker("Method", selection: $selectedString) {
            ForEach(strings, id: \.self) { string in
                Text(string)
            }
        }
        .labelsHidden() // the label is in the Text view
    }
}
  1. Hide the Picker label by using the .labelsHidden() modifier.
  2. Use the .fixedSize() modifier on the new Text. This will allow the Picker to expand to fit all its contents.
  3. Use Spacer between Text label and Picker to push both items to the edge.

SwiftUI Picker layout with short content text

SwiftUI Picker layout with longer content text

  • Related