1

No matter what I try, I cannot control the width of a custom picker view integrated into Swift UI with UIViewRepresentable. Here is the ContentView:

struct ContentView: View {
    @State private var pickerData:[[String]] =
        [
            ["silhouette_1" , "silhouette_2" , "silhouette_3" ],
            ["silhouette_2" , "silhouette_3" , "silhouette_1" ],
            ["silhouette_3" , "silhouette_1" , "silhouette_2" ]
        ]
    
       var body: some View {
        VStack{
            SilhouettePickerView(pickerData: $pickerData)
            }
       }
   }

And here is the SilhouettePickerView:

struct SilhouettePickerView: UIViewRepresentable {
    @Binding var pickerData : [[String]]
    func makeCoordinator() -> SilhouettePickerView.Coordinator {
        return SilhouettePickerView.Coordinator(self)
    }

    func makeUIView(context: UIViewRepresentableContext<SilhouettePickerView>) -> UIPickerView {
        let picker = UIPickerView(frame: .zero)
        //let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: ????, height: ?????))

        picker.dataSource = context.coordinator
        picker.delegate = context.coordinator
        return picker
    }
    func updateUIView(_ view: UIPickerView, context: UIViewRepresentableContext<SilhouettePickerView>) {
    }

    class Coordinator: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
        var parent: SilhouettePickerView
        init(_ pickerView: SilhouettePickerView) {
            self.parent = pickerView
        }
   
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return parent.pickerData.count
        }
        
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return parent.pickerData[component].count
        }
        
        func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
            //return UIScreen.main.bounds.width/3
            pickerView.bounds.width/3 - 8
        }

        func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
            return 126
        }
      
        func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {

            let view = UIView(frame: CGRect(x: 0, y: 0, width:pickerView.bounds.width, height: 0))
            
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 90, height: 126))
            for _ in 0..<self.parent.pickerData.count {
                imageView.image = UIImage(named: self.parent.pickerData[component][row])
            }
            view.addSubview(imageView)
            return view
        }
    }
}

This is the result. Screen Shot of custom picker view

I want it to fill up more of the screen. Also, I want the component rows centered; you'll notice the gray at the right edge. (Anyway to get rid of that?) I've played around with setting the frame size in makeUIView:

let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 400, height: 200))

But nothing changes. Any suggestions? Thanks!

Hyoryusha
  • 175
  • 1
  • 11
  • Don't set any external limits to UIView and representable layout it automatically in parent SwfitUI view. See for example https://stackoverflow.com/a/62301587/12299030. – Asperi Apr 25 '21 at 09:37
  • Thanks, Asperi. My code in its current state follows the recommendation you made as well as that in the link you provided. The latter says that if it still doesn't work (and it doesn't) I need to look for other errors in the internal view. – Hyoryusha Apr 25 '21 at 19:52
  • @Hyoryusha did you find a solution? – Mumtaz Hussain Nov 22 '21 at 22:24

0 Answers0