10

With Objective-C, I used the code shown below to set/change font family and size of a picker:

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel* tView = (UILabel*)view;
if (!tView){
    tView = [[UILabel alloc] init];
    // Setup label properties - frame, font, colors etc
    tView.font = [UIFont fontWithName:@"Times New Roman" size:fontsize];;
}
tView.text = [_mysitedata findKeyForRow:row];
NSLog(@"C key:%@ row:%ld comp:%ld", tView.text, (long int)row, (long int)component);
return tView;
}

However, Swift does not accept a cast from UIView to UILabel and hence I can not follow this path which would look something like shown below:

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
    let label = view as! UILabel
    label.font = UIFont(name: "Times New Roman", size: 1.0)
    label.text = pickerData[row]
    return label
}

The first stament (let label ....) throuws an exception at run time:

EXC-BAD INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

GoZoner
  • 67,920
  • 20
  • 95
  • 145
Robert Brusa
  • 322
  • 1
  • 2
  • 11
  • This link [link]http://stackoverflow.com/questions/27455345/uipickerview-wont-allow-changing-font-name-and-size-via-delegates-attributedt[>link] solves the problem. – Robert Brusa Nov 11 '15 at 16:36

5 Answers5

27

For Swift 3

 func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
    let label = (view as? UILabel) ?? UILabel()

    label.textColor = .black
    label.textAlignment = .center
    label.font = UIFont(name: "SanFranciscoText-Light", size: 18)

    // where data is an Array of String
    label.text = pickerData[row]

    return label
  }
Ulug'bek
  • 2,762
  • 6
  • 31
  • 59
Wilson
  • 9,006
  • 3
  • 42
  • 46
6

To change the font name and size you can use viewForRow and an attributed string:

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {

    var label = view as! UILabel!
    if label == nil {
        label = UILabel()
    }

    var data = pickerData[row]
    let title = NSAttributedString(string: data!, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(36.0, weight: UIFontWeightRegular)])
    label.attributedText = title
    label.textAlignment = .Center
    return label

}

And if you make your font size larger you'll want to increase the height of each row with rowHeightForComponent:

func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
    return 36.0
}
John Pavley
  • 5,366
  • 2
  • 14
  • 16
5

If you want the picker label to AUTOSHRINK...

Set adjustsFontSizeToFitWidth=true and minimumScaleFactor=0.5

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

    var label: UILabel
    if let view = view as? UILabel { label = view }
    else { label = UILabel() }

    label.text = "..."
    label.textAlignment = .center
    label.font = UIFont.boldSystemFont(ofSize: 20)
    label.adjustsFontSizeToFitWidth = true
    label.minimumScaleFactor = 0.5

    return label
}
Derek Soike
  • 11,238
  • 3
  • 79
  • 74
4

For swift 2.3

 func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView{

        var label = view as! UILabel!
        if label == nil {
            label = UILabel()
        }

        label.font = UIFont(name: "Lato-Regular", size: 17)!
        label.text =  dataArray[row] as? String
        label.textAlignment = .Center
        return label

    }

For Swift 3

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView{

        print("Returning Custom label")
        var label = view as! UILabel!
        if label == nil {
            label = UILabel()
        }

        label?.font = UIFont(name: "Lato-Regular", size: 14)!
        label?.text =  dataArray[row] as? String
        label?.textAlignment = .center
        return label!

    }
Md. Sajedul Karim
  • 6,749
  • 3
  • 61
  • 87
Nischal Hada
  • 3,230
  • 3
  • 27
  • 57
1

A more idiomatic Swift coding would be:

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
  guard let label = view as? UILabel else {
    preconditionFailure ("Expected a Label")
  }

  label.font = UIFont(name: "Times New Roman", size: 1.0)
  label.text = pickerData[row]
  return label
}
GoZoner
  • 67,920
  • 20
  • 95
  • 145
  • 1
    For those of you like me that got an error when trying this approach, and spent too much time trying to figure out what was wrong, an alternative approach that does work is here: http://stackoverflow.com/questions/27455345/uipickerview-wont-allow-changing-font-name-and-size-via-delegates-attributedt – Ben Sep 05 '16 at 17:19