UIPickerView: NSAttributedString not available in iOS 7?
Asked Answered
M

3

8

It seems the UIPickerView no longer supports the use of NSAttributedString for picker view items. Can anyone confirm this? I found NS_AVAILABLE_IOS(6_0) in the UIPickerView.h file, but is this the problem? Is there a way around this, or am I out of luck?

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component NS_AVAILABLE_IOS(6_0); // attributed title is favored if both methods are implemented
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view;
Multicellular answered 22/9, 2013 at 14:54 Comment(6)
What happens when you supply an attributed string? How is it not supported?Vann
My apologies I probably should have mentioned this. It runs perfectly fine, but the pickerView does not display it with the specified fonts on iOS 7. It ONLY uses the system default. On iOS 6 this does display in the font it's supposed to.Multicellular
Did you try returning a label with the attributed text as an alternative approach?Vann
Seems pretty straightforward if it works in iOS6 but not 7. The first thing you should do in this case is build a quick demo app that demonstrates the bug and file a bug report with Apple (bugreporter.apple.com), attaching the demo app.They
That still works Wain. I don't see how Apple could be unaware of this!Multicellular
I have noticed that fonts have no affect, but NSForegroundColorAttributeName seems to work.Valued
M
15

The only solution to this problem is apparently to use pickerView:viewForRow:forComponent:reusingView: and return a UILabel with the attributed text, since Apple has apparently disabled using attributed strings otherwise.

Multicellular answered 22/9, 2013 at 15:27 Comment(2)
The only issue with this approach is that views in picker view don't get the nice zoom effect when selected but strings do.Calyptra
I agree, and I'm not sure there's actually a way to implement it yourself. It's an unfortunate problem with Apple breaking their own code yet again.Multicellular
D
7

Rob is right, bug or not the easiest way to get attributed text in a UIPickerView in iOS 7 is to hack the pickerView: viewForRow: forComponent: reusingView: method. Here's what I did...

-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
    // create attributed string
    NSString *yourString = @"a string";  //can also use array[row] to get string
    NSDictionary *attributeDict = @{NSForegroundColorAttributeName : [UIColor whiteColor]};
    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:yourString attributes:attributeDict];

    // add the string to a label's attributedText property
    UILabel *labelView = [[UILabel alloc] init];
    labelView.attributedText = attributedString;

    // return the label
    return labelView;
}

It looks great on iOS 7, but in iOS 6 the default background is white so you can't see my white text. I'd suggest checking for iOS version and implementing different attributes based on each.

Deprive answered 30/9, 2013 at 20:16 Comment(1)
github.com/erica/iOS-6-Advanced-Cookbook/tree/master/… This is a good library to use for checking just about everything about a device. Grab UIDevice-Hardware.hMulticellular
S
4

Here's an example of using pickerView:viewForRow:forComponent:reusingView: in a way that honors the recycled views.

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UILabel *)recycledLabel {
    UILabel *label = recycledLabel;
    if (!label) { // Make a new label if necessary.
        label = [[UILabel alloc] init];
        label.backgroundColor = [UIColor clearColor];
        label.textAlignment = NSTextAlignmentCenter;
    }
    label.text = [self myPickerTitleForRow:row forComponent:component];
    return label;
}
Staphyloplasty answered 2/9, 2014 at 0:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.