Search code examples
xcodeswiftuiuipickerviewuiviewrepresentable

UIPickerView with UIViewRepresentable does not fill the whole width


Unfortunately, when I create a UIPickerView in SwiftUI with UIViewRepresenable it doesn't fill the whole screen. I've also tried giving it a lot of frame modifiers, but nothing worked. Does anyone have a solution for this or knows why the width of the entire screen is not filled with the picker? Best regards

This is the Code:

struct MultiComponentsPicker: UIViewRepresentable {
    
    @Binding var hours: Int
    @Binding var minutes: Int
    @Binding var seconds: Int
    
    func makeUIView(context: Context) -> UIPickerView {
        let pickerView = UIPickerView()
        pickerView.delegate = context.coordinator
        pickerView.dataSource = context.coordinator
        
        return pickerView
    }
    
    func updateUIView(_ uiView: UIPickerView, context: Context) {
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
        
        let parent: MultiComponentsPicker
        
        init(_ parent: MultiComponentsPicker) {
            self.parent = parent
        }
        
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 6
        }
        
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            if component == 0 {
                return 24
            }
            
            else if component == 1 {
                return 1
            }
            
            else if component == 2 {
                return 60
            }
            
            else if component == 3 {
                return 1
            }
            
            else if component == 4 {
                return 60
            }
            
            else if component == 5 {
                return 1
            }
            
            return 0
        }
        
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            if component == 0 {
                return "\(row)"
            }
            
            else if component == 1 {
                return "Std."
            }
            
            else if component == 2 {
                return "\(row)"
            }
            
            else if component == 3 {
                return "Min."
            }
            
            else if component == 4 {
                return "\(row)"
            }
            
            else if component == 5 {
                return "Sek."
            }
            
            
            return ""
        }
        
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            if component == 0 {
                parent.hours = Int(row.description)!
            }
            
            else if component == 2 {
                parent.minutes = Int(row.description)!
            }
            
            else if component == 4 {
                parent.seconds = Int(row.description)!
            }
        }
    }
}

And thats what it looks like:

enter image description here


Solution

  • in the UIViewRepresentable:

        // allows rows to be compressed
        pickerView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        // allows rows to be expanded
        pickerView.setContentHuggingPriority(.defaultLow, for: .horizontal)
    

    in the View:

        MultiComponentsPicker(hours: $hours, minutes: $minutes, seconds: $seconds)
            .frame(width: .infinity) // or fixed size