Home > Net >  How to make SwiftUI Picker Wrap Text
How to make SwiftUI Picker Wrap Text

Time:07-19

When using a Picker with .pickerStyle(WheelPickerStyle()), the horizontal space that the picker takes up is seemingly fixed. In the image below, the Picker frame (which is seen by its lighter color) is larger than it needs to be for its elements.

Screenshot

I'm trying to get the picker to only be as wide as it needs to be for the longest option it contains, similar to how Text() views "wrap" their text, and are only as big as the text inside them requires them to be.

How can I accomplish this for a Wheel Picker in SwiftUI?

CodePudding user response:

A solution appears a bit complicated because Picker is not native SwiftUI control, but has UIPickerView at backend, so we need combination of already mentioned one demo

Main part is

@State private var maxWidth = CGFloat.zero
@State private var width = CGFloat.infinity

var body: some View {
    Picker("", selection: $selection) {
        ForEach( ... 

           // Row/Label view is here

            .background(GeometryReader {
                Color.clear.preference(key: ViewWidthKey.self,
                    value: $0.frame(in: .local).size.width)
            })
            .onPreferenceChange(ViewWidthKey.self) {
                self.maxWidth = max($0, maxWidth)
                width = max($0, maxWidth)
            }
        }
    }
    .pickerStyle(.wheel)
    .frame(maxWidth: width   2 * 20 /* padding on both sides */)
}

Tested with Xcode 13.4 / iOS 15.5

Test code on GitHub

  • Related