customize text width of picker

Discussion in 'iOS Programming' started by JPfowl, Oct 7, 2013.

  1. JPfowl macrumors newbie

    Joined:
    Sep 29, 2013
    #1
    I'm new to programming iOS, and am doing it for a class. We have a picker that used to be states and zip codes but I changed it to be species and animal. It used a dictionary and I edited it to have my content. The picker runs but the text of the animals and species is too wide to fit all on screen. Is there a way to change the text size?
     
  2. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #2

    You need to implement the UIPickerViewDelegate method pickerView:widthForComponent:

    That lets you tell the picker how wide each component needs to be.

    The simplest thing to do would be to manually find the widest string you need to display for each component in your picker and manually change your code to return that width.

    You could get fancier and at startup calculate the width of all the strings in the data for each component (using the sizeWithFont: method or the new iOS 7 replacement), and save the widest value, then return those values in the pickerView:widthForComponent: delegate method.
     
  3. JPfowl, Oct 7, 2013
    Last edited: Oct 7, 2013

    JPfowl thread starter macrumors newbie

    Joined:
    Sep 29, 2013
    #3

    I have this but even when I make it for the widest string the text simply overflows the picker. The text doesn't autoscale to fit.
    Code:
    - (CGFloat)pickerView:(UIPickerView *)pickerView
        widthForComponent:(NSInteger)component
    {
        if (component == kZipComponent) {
            return 200;
        } else {
            return 100;
        }
    }
    [​IMG]
     
  4. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #4

    I don't understand. If you return a value wide enough for the longest string, why would you need the picker to autoscale the text?

    I'm not sure if pickers support autoscaling. If you want that, you might need to implement the pickerView:viewForRow:forComponent:reusingView method instead of pickerView:titleForRow:forComponent, and build a UILabel with adjustsFontSizeToFitWidth = TRUE and a minimumScaleFactor that lets the label resize the text smaller.
     
  5. JPfowl thread starter macrumors newbie

    Joined:
    Sep 29, 2013
    #5
    If you saw the picture I added then you see that the picker adds ellipses to the text and shortens it. I just want it to show all the text somehow.
     
  6. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #6
    So why not set the width to be long enough for your longest string?

    If you can't do that, use the other delegate method and create labels for each section/row, where you specify a minimum display scale, as I said in my last post.
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    Maybe a picker isn't the best way to build this UI.

    What's your longest description?
     
  8. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #8
    If you want help, please respond to this post.
     
  9. JPfowl thread starter macrumors newbie

    Joined:
    Sep 29, 2013
    #9
    Sorry, I've had lots of exams I had to study for. I'm getting the idea of what you're saying but I have never used a scaling factor. Can you explain (and possibly give an example?)?
     
  10. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #10
    No, I don't have an example to give you.

    The simplest way to use a picker is to provide strings for each item. The system then builds the picker.

    The other way to do it is to implement the pickerView:viewForRow:forComponent:reusingView: method. That method returns a VIEW for each spot in the picker, and the picker uses that view for that location.

    If you do that, you could create a UILabel for each spot, and set the minimumScaleFactor property on the label. That property tells the label that it can scale the text down if needed to fit in the label's frame. Search for "minimumScaleFactor" in the UILabel class reference in Xcode for more information.

    Something like this:

    Code:
    - (UIView *)pickerView: (UIPickerView *) pickerView 
                    viewForRow: (NSInteger) row 
                 forComponent: (NSInteger) component 
                    reusingView: (UIView *)view
    {
       UILabel *label = (UILabel *) view;
    
      if (label == nil)
      {
        CGRect frame = CGRectMake(0, 0, 120, 30); //These values are made up. Figure out better ones.
        label = [UILabel alloc] initWithFrame: frame];
        label.minimumScaleFactor = 0.75; //Allow the text to shrink to 75%
        label.font = [UIFont systemFontOfSize: 14]; //Pick a small size to start
      }
      //Now fetch the string for this cell in the 
      //picker and install it in the label.
      NSString *string;
      string = //Put code here that fetches the string you want.
      label.text = string;
    
      return label;
    }
    
     

Share This Page