I am trying to make a horizontal UIPivkerView
. I did everything but I do not understand how to set the size for a cell because some words are too long. I tried to learn the length of each word and based on it set the cell size. But it not work for me. I noticed that I can increase the size of the cell if I increase its size and width in proportion too.
I need a make PickerView
with like 50 width
and 50 height
but I do not understand how to deal with cells.
If I set value 85
I get this:
If set 50
:
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var data = ["Hello", "WorldWorld", "Of", "PickerPickerPicker", "View"]
let viewPicker = UIPickerView()
var rotationAngele: CGFloat!
var width: CGFloat = 85
var height: CGFloat = 85
//var width: CGFloat!
override func viewDidLoad() {
super.viewDidLoad()
viewPicker.delegate = self
viewPicker.dataSource = self
viewPicker.layer.borderColor = UIColor.black.cgColor
viewPicker.layer.borderWidth = 1.5
// Rotation
rotationAngele = -90 * (.pi / 180)
viewPicker.transform = CGAffineTransform(rotationAngle: rotationAngele)
//width = data[4].widthOfString(usingFont: UIFont(name:"verdana", size: 24.0)!)
// Create
viewPicker.frame = CGRect(x: 0 - 150, y: 0, width: view.frame.width + 300, height: 85)
viewPicker.center = self.view.center
self.view.addSubview(viewPicker)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return data.count
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 85
}
func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
return 85
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
//width = data[row].widthOfString(usingFont: UIFont(name:"verdana", size: 24.0)!)
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: 150, height: 150)
let label = UILabel()
label.frame = CGRect(x: 0, y: 0, width: 150, height: 150)
label.textAlignment = .center
label.font = UIFont(name:"verdana", size: 24.0)!
label.text = data[row]
view.addSubview(label)
view.transform = CGAffineTransform(rotationAngle: 90 * (.pi / 180))
return view
}
}
////////////////////////////////////////////////////
extension String {
func widthOfString(usingFont font: UIFont) -> CGFloat {
let fontAttributes = [NSAttributedStringKey.font: font]
let size = self.size(withAttributes: fontAttributes)
return size.width
}
func heightOfString(usingFont font: UIFont) -> CGFloat {
let fontAttributes = [NSAttributedStringKey.font: font]
let size = self.size(withAttributes: fontAttributes)
return size.height
}
}
Ok, when you rotate UIPickerView
by applying transform, when you specify the component width you actually specifying the rowHeight.
It's not that clear if you inspect the view but if you log the frame size you will understand.
So you should set the pickerView:rowHeightForComponent
to make it wide enough
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
return 300 // you can calculate this based on your container view or window size
}
Further you can also use intrinsicContentSize
of UILabel
to figure out the correct size of the label and update its frame accordingly to make sure the label also rendered correctly.
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: 150, height: 30)
let label = UILabel()
label.frame = CGRect(x: 0, y: 0, width: 150, height: 30)
label.textAlignment = .center
label.font = UIFont(name:"verdana", size: 24.0)!
label.text = data[row]
let updatedLabelSize = label.intrinsicContentSize
dump(updatedLabelSize)
label.frame = CGRect(x: 0, y: 0, width: updatedLabelSize.width, height: 30)
view.frame = CGRect(x: 0, y: 0, width: updatedLabelSize.width, height: 30)
view.addSubview(label)
view.transform = CGAffineTransform(rotationAngle: 90 * (.pi / 180))
return view
}
Here is how UIPickerView actually look like when you transform it. Red box is after transformation, things that you see Blue highlight is the real frame