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?
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
}
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,
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.
Fonctionne pour Swift 2, 3, 4 et probablement pour Swift <2. (non testé)
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.
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.
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())
[date_picker setValue:textColor forKey:@"textColor"];
[date_picker performSelector:@selector(setHighlightsToday:) withObject:NO];
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.
}
}
}
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
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;
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
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