web-dev-qa-db-fra.com

Changer la couleur de la police UIDatePicker?

Tout ce que je veux faire, c'est changer la couleur de police de l'UIDatePicker. J'ai recherché d'autres questions, mais elles impliquent toutes de modifier d'autres propriétés et de personnaliser l'ensemble du look. Tout ce que je veux faire, c'est simplement changer la couleur de la police du noir au blanc. J'ai du mal à croire que je ne peux pas faire une tâche aussi simple en apparence. Et pourquoi la couleur de la teinte ne l'affecterait-elle pas? Cela fait-il même quelque chose?

33
Milo

Tout ce dont j'ai besoin (sur iOS 8.x et 9.0) est cette seule ligne pour changer la couleur de la police:

        [my_date_picker setValue:[UIColor whiteColor] forKey:@"textColor"];

Pas de sous-classement ou d'invocation d'API privées ...


Remarque: la date actuelle du jour sera toujours mise en évidence (dans les versions iOS plus récentes). Vous pouvez contourner cela en utilisant le code suivant:

if ([my_date_picker respondsToSelector:sel_registerName("setHighlightsToday:")]) {

#pragma clang diagnostic Push
#pragma clang diagnostic ignored "-Wundeclared-selector"

        [my_date_picker performSelector:@selector(setHighlightsToday:) withObject:[NSNumber numberWithBool:NO]];

#pragma clang diagnostic pop

}
69
waffles

Au Swift 2.1:

picker.setValue(UIColor.whiteColor(), forKey: "textColor")
picker.sendAction("setHighlightsToday:", to: nil, forEvent: nil)
let date = NSDate()
picker.setDate(date, animated: false)

Au lieu de "aujourd'hui", vous verrez le jour actuel,

22
DCDC

La prochaine solution vient de "arturgrigor" et elle fonctionne très bien dans mes applications, copiez-la, collez-la dans la méthode viewDidLoad et profitez-en:

[my_datePicker setValue:[UIColor whiteColor] forKeyPath:@"textColor"];
SEL selector = NSSelectorFromString( @"setHighlightsToday:" );
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature :
                           [UIDatePicker 
                            instanceMethodSignatureForSelector:selector]];
BOOL no = NO;
[invocation setSelector:selector];
[invocation setArgument:&no atIndex:2];
[invocation invokeWithTarget:my_datePicker];

Une autre alternative à @ Jeremiah answer est de définir ces valeurs dans Interface Builder. Je préfère celui-ci car il n'y a pas de code à ajouter dans votre ViewController.

Cliquez dans votre vue DatePicker et personnalisez-la à partir de l'inspecteur d'attributs comme dans la capture d'écran. screenshot

Fonctionne pour Swift 2, 3, 4 et probablement pour Swift <2. (non testé)

14
Toldy

Selon Apple's UIKit User Interface Catalog , les développeurs ne sont pas autorisés à personnaliser les sélecteurs de date.

J'ai vu d'autres réponses StackOverflow pour des questions similaires qui suggèrent de créer un faux UIDatePicker en utilisant UIPickerView et de le personnaliser .

J'ai également trouvé un sélecteur de date open source sur GitHub (à https://github.com/mwermuth/MWDatePicker) qui pourrait aider un peu. Il permet différents styles d'arrière-plan et de sélecteur, mais pas une police ou des attributs de police différents .... pour le moment.

7
Michael Dautermann

Pour modifier la couleur du texte UIDatePicker, utilisez:

    // MARK: - Helping content 

    private enum DatePickerProperties: String {
        case TextColor = "textColor"
        case HighlightsToday = "highlightsToday"
    }

    // MARK: - Outlets

    @IBOutlet private weak var datePicker: UIDatePicker!

    // MARK: - Lifecicle

    public override func awakeFromNib() {
        super.awakeFromNib()

        self.datePicker.setValue(UIColor.whiteColor(), forKey: DatePickerProperties.TextColor.rawValue)
        self.datePicker.setValue(false, forKey: DatePickerProperties.HighlightsToday.rawValue)
    }

Cela fonctionne comme un charme avec xCode 7.3 et Swift 2.3.

6
Daniel Sumara

Si quelqu'un veut la solution Swift, j'ai placé ce qui suit dans viewDidLoad:

    birthdayDatePicker.setValue(DesignHelper.getOffWhiteColor(), forKey: "textColor")
    birthdayDatePicker.performSelector("setHighlightsToday:", withObject:DesignHelper.getOffWhiteColor())
4
Jeremiah
[date_picker setValue:textColor forKey:@"textColor"];
[date_picker performSelector:@selector(setHighlightsToday:) withObject:NO];
2
Srj0x0

Vous pouvez également l'ajouter en tant qu'IBDesignable si vous souhaitez le configurer dans InterFace Builder.

    import UIKit

@IBDesignable
extension UIDatePicker {
    @IBInspectable var textLabelColor: UIColor? {
        get {
            return self.valueForKey("textColor") as? UIColor
        }
        set {
            self.setValue(newValue, forKey: "textColor")
            self.performSelector("setHighlightsToday:", withObject:newValue) //For some reason this line makes the highlighted text appear the same color but can not be changed from textColor. 
        }
    }
}
2
BandoKal

Pour les développeurs Xamarin:

DatePicker.SetValueForKey(UIColor.White, new NSString("textColor"));
DatePicker.SetValueForKey(FromObject(false), new NSString("highlightsToday"));

Cela fonctionne comme un charme. Testé sur iOS 9 et 10

2
xleon

Je suis tombé sur une solution étonnamment propre utilisant UIAppearance, sans utiliser d'API KVC, de swizzling ou autrement privée. J'ai trouvé que la tentative de définir le textColor via UIAppearance pour tout UILabel dans un UIDatePicker n'avait aucun effet, mais une propriété d'apparence personnalisée qui appelait simplement le normal textColor setter a très bien fonctionné.

// Implement a custom appearance property via a UILabel category
@interface UILabel (PickerLabelTextColor)

@property (nonatomic, strong) UIColor * textColorWorkaround UI_APPEARANCE_SELECTOR;

@end

@implementation UILabel (PickerLabelTextColor)

- (UIColor *)textColorWorkaround {
    return self.textColor;
}

- (void)setTextColorWorkaround:(UIColor *)textColor {
    self.textColor = textColor;
}

@end

Et puis utilisez comme suit:

UILabel *pickerLabelProxy = [UILabel appearanceWhenContainedInInstancesOfClasses:@[UIDatePicker.class]];
pickerLabelProxy.textColorWorkaround = UIColor.lightGrayColor;
2
gyratory circus

Cette sous-classe d'UIDatePicker fonctionne pour iOS 7. Ce n'est pas joli mais fait le travail.

#define kNotification_UIView_didAddSubview @"kNotification_UIView_didAddSubview"
@implementation UIView (addSubview)

-(void) didAddSubview:(UIView *)subview{
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotification_UIView_didAddSubview object:self];
}
@end


@interface DatePicker ()
@property (nonatomic, strong) UIColor* textColor;
@end

@implementation DatePicker

-(id) initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self){
        [self setup];
    }
    return self;
}
-(id) initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self){
        [self setup];
    }
    return self;
}

-(void) setup{
    self.textColor = [UIColor darkTextColor];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subviewsUpdated:) name:kNotification_UIView_didAddSubview object:nil];
}

-(void) dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(void) updateLabels:(UIView*) view{
    for (UILabel* label in view.subviews){
        if ([label isKindOfClass:[UILabel class]]){
            label.textColor = self.textColor;
        }else{
            [self updateLabels:label];
        }
    }
}

-(BOOL) isSubview:(UIView*) view{
    if (view == nil){
        return NO;
    }
    if (view.superview == self){
        return YES;
    }
    return [self isSubview:view.superview];
}

-(void) subviewsUpdated:(NSNotification*) notification{
    if ([notification.object isKindOfClass:NSClassFromString(@"UIPickerTableView")] && [self isSubview:notification.object]){
        [self updateLabels:notification.object];
    }
}

@end
2
datinc

Comme alternative à la réponse @Jeremiah, vous pouvez utiliser ceci:

datePicker.setValue(UIColor.redColor(), forKey: "textColor")
datePicker.sendAction("setHighlightsToday:", to: nil, forEvent: nil)
datePicker.setDate(NSDate(timeIntervalSinceReferenceDate: 0), animated: false)

il supprimera Aujourd'hui (vous verrez la date actuelle), mais ce sera avec la bonne couleur.

Problèmes possibles: si vous changez de couleur dynamiquement, je n'ai pas trouvé de moyen de recharger le sélecteur de date. Ainsi, l'utilisateur verra la couleur précédente et seulement après le défilement, la couleur sera changée en une nouvelle. -> Résolu, par la dernière chaîne. On dirait du vaudou, mais ça marche ...

Cette réponse convient pour Swift 2.1

1
Dima Deplov

Ajoutez l'attribut d'exécution nommé "textColor" à partir de Storyboard comme indiqué dans l'image suivante.

enter image description here

1
Mehul Thakkar