Multi-Component Picker (UIPickerView) in SwiftUI
Here's an adaptation of the solutions above, using the UIKit picker:
import SwiftUI
struct PickerView: UIViewRepresentable {
var data: [[String]]
@Binding var selections: [Int]
//makeCoordinator()
func makeCoordinator() -> PickerView.Coordinator {
Coordinator(self)
}
//makeUIView(context:)
func makeUIView(context: UIViewRepresentableContext<PickerView>) -> UIPickerView {
let picker = UIPickerView(frame: .zero)
picker.dataSource = context.coordinator
picker.delegate = context.coordinator
return picker
}
//updateUIView(_:context:)
func updateUIView(_ view: UIPickerView, context: UIViewRepresentableContext<PickerView>) {
for i in 0...(self.selections.count - 1) {
view.selectRow(self.selections[i], inComponent: i, animated: false)
}
}
class Coordinator: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
var parent: PickerView
//init(_:)
init(_ pickerView: PickerView) {
self.parent = pickerView
}
//numberOfComponents(in:)
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return self.parent.data.count
}
//pickerView(_:numberOfRowsInComponent:)
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.parent.data[component].count
}
//pickerView(_:titleForRow:forComponent:)
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.parent.data[component][row]
}
//pickerView(_:didSelectRow:inComponent:)
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.parent.selections[component] = row
}
}
}
import SwiftUI
struct ContentView: View {
private let data: [[String]] = [
Array(0...10).map { "\($0)" },
Array(20...40).map { "\($0)" },
Array(100...200).map { "\($0)" }
]
@State private var selections: [Int] = [5, 10, 50]
var body: some View {
VStack {
PickerView(data: self.data, selections: self.$selections)
Text("\(self.data[0][self.selections[0]]) \(self.data[1][self.selections[1]]) \(self.data[2][self.selections[2]])")
} //VStack
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
How to change UIPickerView width with multiple Pickers in SwiftUI?
You need to remove compression resistance priority
let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
picker.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
and then can use any frame as you need in SwiftUI part (static or calculated)
MainPicker(pickerSelections: self.$selections)
.frame(width: 200)
Demo prepared & tested with Xcode 11.7 / iOS 13.7
SwiftUI: How to center multi column picker on screen
Not really sure the final goal, but for provided code it can be done just by making Stack
consume all space provided by GeometryReader
, like
HStack{
// ... other code here
}
.frame(maxWidth: .infinity) // << this one !!
Tested with Xcode 12.4 / iOS 14.4
SwiftUI - Placing two pickers side-by-side in HStack does not resize pickers
The overlapping in the middle you can fix by adding a clipped() modifier. As for the width, I see them both exactly the same:
struct ContentView: View {
@State var selection1: Int = 0
@State var selection2: Int = 0
@State var integers: [Int] = [0, 1, 2, 3, 4, 5]
var body: some View {
GeometryReader { geometry in
HStack(spacing: 0) {
Picker(selection: self.$selection1, label: Text("Numbers")) {
ForEach(self.integers) { integer in
Text("\(integer)")
}
}
.frame(maxWidth: geometry.size.width / 2)
.clipped()
.border(Color.red)
Picker(selection: self.$selection2, label: Text("Numbers")) {
ForEach(self.integers) { integer in
Text("\(integer)")
}
}
.frame(maxWidth: geometry.size.width / 2)
.clipped()
.border(Color.blue)
}
}
}
}
Related Topics
Remove Multiple Indices from Array
Swift: Popover Dismiss Callback
How to Connect Localhost (With Invalid Certificate) Using Alamofire
Result Values in '? :' Expression Have Mismatching Types 'Some View' and '...'
How to Connect Aksequencer to a Akcallbackinstrument
How to Create a Noop Block for a Switch Case in Swift
Swift Extension for Selected Class Instance
Swift Programmatically Set Segues
Retrieving Keys from Geofire Within Radius in Swift
How to Resume Audio After Interruption in Swift
Scenekit - Scntext Centering Incorrectly
What Are Convenience Required Initializers in Swift
Wait Until an Asynchronous API Call Is Completed - Swift/Ios
Get Header Data from a Request Response in Swift
Is It the Right Way Using '[Weak Self]' in Swift Closure