Search code examples
swiftuipickerview

swift uipickerview height change not working


I know this questions has been asked multiple times, but I have followed most of the links in stack overflow but no answer seems to work. Also I saw somewhere that only 3 heights are allowed that too are above 160 which I don't want in my case. So please suggest a workaround

This are the codes I have tried

//this label doesn't matter
let classLabel: UILabel = {
    let label = UILabel()
    label.text = "Select Class"
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

//first try
var classPicker = UIPickerView(frame: CGRect(x: 0.0, y: 0.0, width:
30.0, height: 30.0))

//second try
var classPicker: UIPickerView = {
    let picker = UIPickerView(frame: CGRect(x: 0.0, y: 0.0, width: 10.0, height: 10.0))
    picker.translatesAutoresizingMaskIntoConstraints = false
    return picker
}()

//third 
lazy var chooseClass: UIStackView = {
    classPicker.clipsToBounds = true
    classPicker.heightAnchor.constraint(equalToConstant: 30.0)
    let stackView: UIStackView = UIStackView(arrangedSubviews: [self.classLabel, self.classPicker])
    stackView.axis = .horizontal
    stackView.distribution = .fillEqually
    stackView.alignment = .fill
    stackView.spacing = 10.0
    stackView.translatesAutoresizingMaskIntoConstraints = false
    return stackView
}()

 //and then

 chooseClass.heightAnchor.constraint(equalToConstant: 30.0)

enter image description here

Also I have tried answers from this link but it didn't work How to change UIPickerView height


Solution

  • You need to change the stackView alignment to .center. Then you can add witdth and height anchors as needed as long as it satisfies the stackView conditions.

    class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
        lazy var classLabel: UILabel = {
            let label = UILabel(frame: .zero)
            label.text = "Select Class"
            return label
        }()
    
        lazy var classPicker: UIPickerView = {
            let pickerView = UIPickerView(frame: .zero)
            pickerView.delegate = self
            pickerView.dataSource = self
            return pickerView
        }()
    
        lazy var chooseClass: UIStackView = {
            let stackView: UIStackView = UIStackView(frame: .zero)
            stackView.axis = .horizontal
            stackView.distribution = .fillEqually
            stackView.alignment = .center
            stackView.spacing = 10.0
            return stackView
        }()
    
        var dataSource = [1,2,3,4]
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.backgroundColor = .white
    
            view.addSubview(chooseClass)
            chooseClass.translatesAutoresizingMaskIntoConstraints = false
            chooseClass.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            chooseClass.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
            chooseClass.heightAnchor.constraint(equalToConstant: 50).isActive = true
            chooseClass.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
    
            classPicker.heightAnchor.constraint(equalToConstant: 30).isActive = true
            chooseClass.addArrangedSubview(classLabel)
            chooseClass.addArrangedSubview(classPicker)
        }
    
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
    
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return dataSource.count
        }
    
        func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
            let label = UILabel()
            label.text = String(dataSource[row])
            label.font = UIFont.systemFont(ofSize: 12, weight: .medium)
            return label
        }
    
    }
    

    I have used viewForRow delegate because at height 30 the titles using titleForRow are cropped at the top and bottom. You should take care of alignment issues, etc. This does what you ask - change the height of the pickerView to 30 while maintaining the stackView height.