64

I have one UIPickerView. This is having nearly 200 items, each items has long texts, so, i want to resize the UIPickerView's font size. How can i change it? It is possible? Can any one help me? Thanks !

Yuva.M

Yuvaraj.M
  • 9,741
  • 16
  • 71
  • 100
  • check http://stackoverflow.com/questions/256556/how-do-i-change-the-text-size-and-component-width-of-a-uipickerview – Narayanan Ramamoorthy Aug 25 '11 at 05:17
  • It may be possible, but I don't think the UIPickerView is supposed to display long texts. It will be tedious for the user to read long texts & even when they are 200 in number. Perhaps you can rethink your design. – Akshay Aug 25 '11 at 05:22
  • Thank you Narayanan Ramamoorthy and Akshay, i solved this problem. Thank you so much for your reply.. – Yuvaraj.M Aug 26 '11 at 04:12

13 Answers13

95

You need to implement pickerView:viewForRow:forComponent:reusingView: method in picker's delegate

- (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
            ...
    }
    // Fill the label text here
    ...
    return tView;
}
Nitish
  • 13,845
  • 28
  • 135
  • 263
32

Update in Swift for iOS8, you can add this to your delegate:

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

    var pickerLabel = view as? UILabel;

    if (pickerLabel == nil)
    {
        pickerLabel = UILabel()

        pickerLabel?.font = UIFont(name: "Montserrat", size: 16)
        pickerLabel?.textAlignment = NSTextAlignment.Center
    }

    pickerLabel?.text = fetchLabelForRowNumber(row)

    return pickerLabel!;
}
bownie
  • 1,608
  • 15
  • 21
26

Swift 4: to update @Alessandro Ornano answer and avoid Force_cast violation error:

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
    var label = UILabel()
    if let v = view as? UILabel { label = v }
    label.font = UIFont (name: "Helvetica Neue", size: 10)
    label.text =  dataArray[row]
    label.textAlignment = .center
    return label
}
Grég
  • 291
  • 3
  • 6
  • 1
    Best answers are always at the bottom of SO!! – Pulkit Apr 18 '19 at 14:37
  • 2
    You're creating a label unncesscerily here... try changing `let label - (view as? Label) ?? UILabel()` or even better call some builder variable that returns you a new label with font and alignment set. Then you don't have to set them every time. – Magoo Jul 06 '20 at 16:13
16

For Font adjustment of UIPickerView Rows

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
    UILabel* pickerLabel = (UILabel*)view;

    if (!pickerLabel)
    {
        pickerLabel = [[UILabel alloc] init];

        pickerLabel.font = [UIFont fontWithName:@"SourceSansPro-Semibold"                size:16];

        pickerLabel.textAlignment=NSTextAlignmentCenter;
    }
    [pickerLabel setText:[self.data objectAtIndex:row]];

    return pickerLabel;
}
0yeoj
  • 4,500
  • 3
  • 23
  • 41
8

Try this, it should help:

  - (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
...
//adjustsFontSizeToFitWidth property to YES
tView.minimumFontSize = 8.;
tView.adjustsFontSizeToFitWidth = YES;
}
// Fill the label text here
...
return tView;
}


// altro modo completo sembrerebbe...
- (UIView *)pickerView:(UIPickerView *)pickerView
viewForRow:(NSInteger)row
forComponent:(NSInteger)component
reusingView:(UIView *)view {

UILabel *pickerLabel = (UILabel *)view;

if (pickerLabel == nil) {
CGRect frame = CGRectMake(0.0, 0.0, 80, 32);
pickerLabel = [[[UILabel alloc] initWithFrame:frame] autorelease];
[pickerLabel setTextAlignment:UITextAlignmentLeft];
[pickerLabel setBackgroundColor:[UIColor clearColor]];
[pickerLabel setFont:[UIFont boldSystemFontOfSize:15]];
}

[pickerLabel setText:[pickerDataArray objectAtIndex:row]];

return pickerLabel;

}
Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Ann
  • 243
  • 2
  • 11
6

Swift 3 | 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 = "My Picker 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
  • row text appears as ... for each row. hmmm. – codeslapper Jun 30 '17 at 12:56
  • not seeing a change in appearance with any of these solutions. This one does change the text to ..., so is running the code. Maybe the UIPickerView needs to be resized somehow or have a setting in InterfaceBuilder? – codeslapper Jun 30 '17 at 13:02
  • @codeslapper Yes, I think the size of your UIPickerView is what's causing the text to appear as "...". Try changing `yourPickerView.frame.size.width` or setting the size via the Interface Builder. – Derek Soike Jul 10 '17 at 19:13
6

Swift 4.x

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        var label = UILabel()
        if let v = view {
            label = v as! UILabel
        }
        label.font = UIFont (name: "Helvetica Neue", size: 10)
        label.text =  dataArray[row]
        label.textAlignment = .center
        return label
    }
Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
3

For Objective c

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{

    UILabel* pickerLabel = (UILabel*)view;
    if (!pickerLabel){
        pickerLabel = [[UILabel alloc] init];
        // Setup label properties - frame, font, colors etc
        [pickerLabel setFont:[UIFont fontWithName:LATO_REGULAR_FONT size:SIZE_SEMIBOLD_FONT]];
        pickerLabel.textColor = primaryTextColor;
        pickerLabel.textAlignment = NSTextAlignmentCenter;


    }
    // Fill the label text here
    pickerLabel.text = self.dataSourceArray[row];

    return pickerLabel;
}

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 = LATO_REGULAR_FONT_17
        label.text =  dataArray[row] as? String
        label.textAlignment = .Center
        return label

    }
Nischal Hada
  • 3,230
  • 3
  • 27
  • 57
3

Clean Swift solution without force unwrapping

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
    let label = (view as? UILabel) ?? UILabel()
    
    // setup label
    
    return label
}
Walter White
  • 315
  • 4
  • 7
1

For RxSwift users, please take away this.

        Observable.just(["option1", "option2", "option3"])
            .bind(to: pickerView.rx.items) { row, option, view in
                let label = (view as? UILabel) ?? .init()
                
                label.font = .preferredFont(forTextStyle: .title1)
                label.adjustsFontSizeToFitWidth = true
                label.minimumScaleFactor = 0.5
                label.text = option
                label.textAlignment = .center
                
                return label
            }
            .disposed(by: bag)

Using iOS predefined title1 font so it can resize according to user's display settings; setting minimumScaleFactor to 0.5 so font can shrink on long text.

One thing to notice is that UIPickerView doesn't seem to allow multi-lines text, even by doing label.numberOfLines = 2 // or 0 won't do you any favour, I guess it is just not designed for displaying long text options.

Daniel Hu
  • 423
  • 4
  • 11
1

Readable Swift version without ! or unnecessary reconfigurations

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
    let label: UILabel = (view as? UILabel) ?? {
        let label: UILabel = UILabel()
        label.font = UIFont.systemFont(ofSize: 12)
        label.textAlignment = .center
        return label
    }()
    label.text = self.pickerView(pickerView, titleForRow: row, forComponent: component)
    return label
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    items[row].title
}
mmackh
  • 3,550
  • 3
  • 35
  • 51
0

To set the system font, need to do bit differently, like below:

let pickerLabel = UILabel()
pickerLabel.font = UIFont.systemFont(ofSize: 20.0, weight: .medium)

you can choose any weight like regular, bold, etc

Pandurang Yachwad
  • 1,695
  • 1
  • 19
  • 29
0

Most answers provide solution for center aligned label. I had to align text to the left side and faced the fact text has been cut off. Adding margin to left solved the problem for me. Solution works for swift 5.

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        
        let pickerLabel: UILabel
        
        if let label = view as? UILabel {
            pickerLabel = label
        } else {
            pickerLabel = UILabel()
            // Customize text
            pickerLabel.font = pickerLabel.font.withSize(20)
            pickerLabel.textAlignment = .left
            pickerLabel.textColor = UIColor.secondaryLabel
            // Create a paragraph with custom style
            // We only need indents to prevent text from being cut off
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.firstLineHeadIndent = 12 // May vary
            // Create a string and append style to it
            let attributedString = NSMutableAttributedString(string: subjects[row])
            attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length))
            // Update label's text
            pickerLabel.attributedText = attributedString
        }
        
        return pickerLabel
    }
mikstime
  • 54
  • 6