UIPickerView: NSAttributedString not available in iOS 7?
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.
Why doesn't attributedTitleForRow get called with a UIPickerView?
I didn't see that the viewForRow
delegate method was also called. If this method is called, neither titleForRow
nor attributedTitleForRow
will run.
Make the text in a pickerView in Swift strikethrough
I ended up using the following after seeing an example at http://makeapppie.com/tag/fonts-in-uipickerview/
This function simply had to be added to existing code. I discovered that every component had to be included or the components other than the check Number component would be blank.
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
let myHueMax = 0.50
let myPickerFontSize: CGFloat = 20.0
print("component in lable == \(component)")
var pickerLabel = view as! UILabel!
var gHue = Double()
if view == nil { //if no label there yet
pickerLabel = UILabel()
//color the label's background
var hue:CGFloat
if component == payeeComponent {
hue = CGFloat(row)/CGFloat(payeesAlphbeticalArray.count)
}else if component == categoryComponent {
hue = CGFloat(row)/CGFloat(categoriesAlphbeticalArray.count)
}else{
hue = CGFloat(row)/CGFloat(checkNumbersAlphbeticalArray.count)
}
pickerLabel!.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness: 1.0, alpha: 1.0)
print("hue in label color == \(hue)")
gHue = Double(hue)
}
if component == payeeComponent {
let titleData = payeesAlphbeticalArray[row]
var myTitle: NSAttributedString
if ( gHue > myHueMax){
myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: myPickerFontSize)!,NSForegroundColorAttributeName:UIColor.whiteColor()])
}else{
myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: myPickerFontSize)!,NSForegroundColorAttributeName:UIColor.blackColor()])
}
pickerLabel!.attributedText = myTitle
pickerLabel!.textAlignment = .Center
return pickerLabel!
}else if component == categoryComponent{
let titleData = categoriesAlphbeticalArray[row]
var myTitle: NSAttributedString
if ( gHue > myHueMax){
myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: myPickerFontSize)!,NSForegroundColorAttributeName:UIColor.whiteColor()])
}else{
myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: myPickerFontSize)!,NSForegroundColorAttributeName:UIColor.blackColor()])
}
pickerLabel!.attributedText = myTitle
pickerLabel!.textAlignment = .Center
return pickerLabel!
}else if component == checkNumberComponent {
if checkNumbersAlphbeticalArray.isEmpty{
return pickerLabel!
}
let titleData = checkNumbersAlphbeticalArray[row]
var myTitle: NSAttributedString
if isCheckNumberUsed(titleData){
if ( gHue > myHueMax){
myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: myPickerFontSize)!,NSForegroundColorAttributeName:UIColor.whiteColor(), NSStrikethroughStyleAttributeName: 1])
}else{
myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: myPickerFontSize)!,NSForegroundColorAttributeName:UIColor.blackColor(), NSStrikethroughStyleAttributeName: 1])
}
}else{
if ( gHue > myHueMax){
myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: myPickerFontSize)!,NSForegroundColorAttributeName:UIColor.whiteColor()])
}else{
myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: myPickerFontSize)!,NSForegroundColorAttributeName:UIColor.blackColor()])
}
}
pickerLabel!.attributedText = myTitle
pickerLabel!.textAlignment = .Center
return pickerLabel!
}
return pickerLabel
}
How can I change text font in UIPickerView in iOS 7?
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel* tView = (UILabel*)view;
if (!tView)
{
tView = [[UILabel alloc] init];
[tView setFont:[UIFont fontWithName:@"Helvetica" size:14]];
//[tView setTextAlignment:UITextAlignmentLeft];
tView.numberOfLines=3;
}
// Fill the label text here
tView.text=[wishvalues objectAtIndex:row];
return tView;
}
Change UIPickerView pickerView:viewForRow: attributes based on a certain condition
If you only want to change the text color just use the other delegate method pickerView:attributedTitleForRow:forComponent:
- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *title;
UIFont *font;
if (row == 1) {
title = [NSString stringWithFormat:@" %@",[self.servicesArray objectAtIndex:row]];
font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:18];
} else{
title = [NSString stringWithFormat:@" -%@",[self.servicesArray objectAtIndex:row] ];
font = [UIFont fontWithName:kAppFont size:16];
}
UIColor *textColor;
if (self.isBackgroundWhite) {
textColor = [UIColor blackColor];
} else {
NSLog(@"Set white text");
textColor = [UIColor whiteColor];
}
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary *attributes = @{NSForegroundColorAttributeName : textColor,
NSFontAttributeName : font,
NSParagraphStyleAttributeName : paragraphStyle};
return [[NSAttributedString alloc] initWithString:title attributes:attributes];
}
Also a note that you should call [self.pickerView reloadAllComponents];
when changing isBackgroundWhite
. I would do this by overriding the setter for backgroundWhite
and when the boolean value changes reload the picker view.
EDIT:
There appears to be a 'bug' (intentional or not) in iOS 7 (works fine on iOS 6) with setting the UIFont
on an NSAttributedString
returned from the pickerView:attributedTitleForRow:forComponent:
method. So while the above works for the text color the font does not change. Luckily you can get around this with the code in the question. See this answer for more info.
iOS 7 UIPickerView non-selected row curvature modification multiple components
The offset is due to the separate, raised plane on which the selector indicator lies. This is actually a fairly accurate rendering of such a real life perspective (of nested, printed, clear cylinders). What Apple does in the Clock app is to right align the picker labels. This ensures that the spacing between the number and its unit label remains constant. You can do the same thing.
First off, in your picker view delegate you want to implement -pickerView:attributedTitleForRow:forComponent: in lieu of -pickerView:titleForRow:forComponent:. (It looks like you’ve already done this given the white text color.) You will use the NSParagraphStyle string attribute. You will need to set two properties on the paragraph style: alignment and tail indent. The alignment should be set to NSTextRightAlignment. The tail alignment will depend on how far you want the labels to sit from the right edge of the component. If you have more than one component, you will need to set the width of the component using -pickerView:widthForComponent:. If you want to keep the curvature to a minimum, set the component width to approximately double the tail indent.
NOTE: If your picker has exactly two components, the width of each component must be less than ⅓ the width of the picker.
Here is a code example:
- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setAlignment:NSTextAlignmentRight];
[paragraphStyle setTailIndent:150];
return [[NSAttributedString alloc] initWithString:@"42"
attributes:@{NSParagraphStyleAttributeName:paragraphStyle}];
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
{
return 300;
}
UIPickerView does not display data in iOS 7
Found out what the problem was.
I was using a empty data set handler, https://github.com/dzenbot/DZNEmptyDataSet, that tried to handle the pickers as well. Removing this handler resolved my problem.
I've learned my lesson, and I've learned it well. 3rd party libraries are a massive gamble.
Cheers.
Change Color of UIPickerView Text
Alternatively you may use the below delegate also and define a UILabel to set your preferred color for the text
– pickerView:viewForRow:forComponent:reusingView:
Related Topics
Could an iOS Application Read/Access Sms Text
How to Delete an App Which Is Waiting for Upload
Stuck on Using Mkpinannotationview() Within Swift and Mapkit
Cannot Show Modal Viewcontroller in iOS7
Swift Execute Asynchronous Tasks in Order
React-Native Loading Image Over Https Works While Http Does Not Work
Warning in Custom Map Annotations Iphone
Ios7 App Backward Compatible with iOS5 Regarding Unique Identifier
Uipinchgesturerecognizer. Make Zoom in Location of Fingers, Not Only Center
Choosing Units with Measurementformatter
Hit Detection When Drawing Lines in iOS
Remote Image Size Without Downloading
Uitextview Linkable Label Accessibility Voice Over Issue
Obtaining Weights in Cvsvm, the Svm Implementation of Opencv
How to Programmatically Get iOS's Alphanumeric Version String
Launchd_Sim Crashing: Could Not Create Temporary State Directory