【问题标题】:Change UIDatePicker font color?更改 UIDatePicker 字体颜色?
【发布时间】:2014-01-19 10:26:23
【问题描述】:

我想要做的就是改变 UIDatePicker 的字体颜色。我研究了其他问题,但它们都涉及更改其他属性和自定义整个外观。我想做的只是将字体颜色从黑色更改为白色。我很难相信我不能完成这样一个看似简单的任务。为什么色调不会影响它?它甚至有什么作用吗?

【问题讨论】:

标签: ios objective-c fonts colors uidatepicker


【解决方案1】:

根据Apple's UIKit User Interface Catalog,不允许开发者自定义日期选择器。

我在 StackOverflow 上看到过针对 suggest making a fake UIDatePicker using UIPickerView and customizing that 的类似问题的其他答案。

I also found an open source date picker on GitHub (at https://github.com/mwermuth/MWDatePicker ) 这可能会有所帮助。它允许使用不同的背景和选择器样式,但不允许使用不同的字体或字体属性......但是。

【讨论】:

  • 谢谢迈克尔。我检查了 MWDatePicker,但它看起来还没有针对 iOS 7 进行更新。当我运行示例项目时,它只是一个空白选择器。我已经决定通过自定义 UIPicker 来模拟 UIDatePicker。谢谢您的帮助。 Apple 不允许自定义日期选择器仍然非常令人惊讶。我想知道这是为什么?
  • 我看到有一个pull request 开放用于将MWDatePicker 现代化到iOS 7。如果所有者合并它会很好,但至少你可以抓住它并使用它。
【解决方案2】:

UIDatePicker 的这个子类适用于 iOS 7。它不是很漂亮,但可以完成工作。

#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

【讨论】:

    【解决方案3】:

    下一个解决方案来自“arturgrigor”,它在我的应用程序中运行良好,只需复制它,将其粘贴到 viewDidLoad 方法中,然后享受它:

    [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];
    

    【讨论】:

    • 换字体怎么样?
    • 你应该小心这个。这会调用苹果的私有 api,苹果可能会拒绝你的应用!
    • @SarenInden,我的应用程序 Acces-o 和 Acces-o School 使用它,别担心!
    【解决方案4】:

    我所需要的(在 iOS 8.x 和 9.0 上)就是这一行来更改字体颜色:

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

    没有子类化或调用私有 API...


    注意:今天的当前日期仍会突出显示(在较新的 iOS 版本中)。您可以使用以下代码解决此问题:

    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
    
    }
    

    【讨论】:

    • 我试过了,但是今天日期的部分颜色不对,10和10月是黑色的,我不介意年份颜色不对,但是另外两个感觉很奇怪
    • @vshade,你在某处张贴了代码 sn-p 吗?很高兴看看...事情仍在为我工作...
    • 这会将所有文本更改为白色,除了当前日期(例如 2015 年 8 月 2 日,将全部为黑色)。
    • 当前日期[my_date_picker performSelector:@selector(setHighlightsToday:) withObject:NO];
    • 弄清楚默认样式已更改,以获取轮子样式返回 picker.preferredDatePickerStyle = .wheels 是必需的,然后此解决方案继续工作
    【解决方案5】:

    如果您想在 InterFace Builder 中配置它,您也可以将它添加为 IBDesignable。

        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. 
            }
        }
    }
    

    【讨论】:

      【解决方案6】:

      如果有人想要快速解决方案,我在 viewDidLoad 中放置了以下内容:

          birthdayDatePicker.setValue(DesignHelper.getOffWhiteColor(), forKey: "textColor")
          birthdayDatePicker.performSelector("setHighlightsToday:", withObject:DesignHelper.getOffWhiteColor())
      

      【讨论】:

      • 太棒了!Swift
      • 无论如何要删除 xcode 7.3 中的警告 - 没有使用 Objective-C 选择器“setHighlightsToday:”声明的方法?
      • 我还没有找到。我已经确认它有效并且仍然需要。如果有人有办法做到这一点而不会收到警告,那就太棒了!
      • 要抑制警告,请查看此解决方案 stackoverflow.com/questions/194666/…
      【解决方案7】:

      作为@Jeremiah 答案的替代方案,您可以使用这个:

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

      它将删除今天(您将看到当前日期),但颜色正确。

      可能的问题: 如果您动态更改颜色,我没有找到重新加载日期选择器的方法。因此,用户将看到以前的颜色,并且只有在滚动后,颜色才会更改为新颜色。 -> 通过最后一个字符串解决。看起来像 Voodoo,但它确实有效......

      这个答案适合 Swift 2.1

      【讨论】:

        【解决方案8】:

        从 Swift 2.1 开始:

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

        您将看到当前日期,而不是“今天”,

        【讨论】:

        • setHighlightsToday 导致警告,No method declared with Objective-C selector 'setHighlightsToday:'
        • Swift 3: picker.setValue(UIColor.white, forKey: "textColor") picker.sendAction(Selector(("setHighlightsToday:")), to: nil, for: nil)
        • 在 Xcode12/Swift 5.3 中,…Selector(("setHighlightsToday:"))… 需要将 : 删除为 …Selector(("setHighlightsToday"))…,以免出现运行时崩溃。
        【解决方案9】:
        [date_picker setValue:textColor forKey:@"textColor"];
        [date_picker performSelector:@selector(setHighlightsToday:) withObject:NO];
        

        【讨论】:

          【解决方案10】:

          @Jeremiah answer 的另一种替代方法是在 Interface Builder 中定义这些值。 我更喜欢这个,因为您的 ViewController 中无需添加任何代码。

          点击进入您的 DatePicker 视图并从属性检查器中对其进行自定义,如屏幕截图所示。

          适用于 Swift 2、3、4,可能适用于 Swift

          【讨论】:

          • 不幸的是,这只会给“Today”这个词着色......而没有别的。如果您将 highlightToday 设置为关闭,则 textColor 无效。这是在 Xcode 11 中。
          【解决方案11】:

          要更改 UIDatePicker 文本颜色,请使用:

              // 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)
              }
          

          它与 xCode 7.3 和 Swift 2.3 一起工作就像一个魅力。

          【讨论】:

            【解决方案12】:

            从 Storyboard 中添加名为“textColor”的运行时属性,如下图所示。

            【讨论】:

              【解决方案13】:

              对于 Xamarin 开发人员:

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

              它就像一个魅力。 在 iOS 9 和 10 中测试

              【讨论】:

                【解决方案14】:

                我偶然发现了一个使用 UIAppearance 的非常干净的解决方案,没有使用任何 KVC、swizzling 或其他私有 API。我发现尝试通过UIAppearanceUILabel 中的UIDatePicker 设置textColor 没有任何影响,但是简单地称为常规textColor 设置器的自定义外观属性工作得很好。

                // 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
                

                然后按如下方式使用:

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

                斯威夫特版

                UILabel 扩展:

                extension UILabel {
                    @objc dynamic var textColorWorkaround: UIColor? {
                        get {
                            return textColor
                        }
                        set {
                            textColor = newValue
                        }
                    }
                }
                

                外观代理使用:

                let pickerLabelProxy = UILabel.appearance(whenContainedInInstancesOf: [UIDatePicker.self])
                pickerLabelProxy.textColorWorkaround = UIColor.lightGray
                

                【讨论】:

                • 您能否提供此解决方案的快速版本
                • @keegan3d 已添加!它可以编译并且在功能上应该是等效的,但是我最近没有使用过这个策略。让我们知道它是否仍然有效!
                【解决方案15】:

                直到在 layoutSubviews() 中设置 textColor 后它才起作用

                override func layoutSubviews() {
                    super.layoutSubviews()
                    datePicker.backgroundColor = .black
                    datePicker.setValue(.white, forKeyPath: "textColor")
                }
                

                【讨论】:

                  【解决方案16】:

                  只需使用datePicker.tintColor = .red 或您想要的任何其他颜色。

                  【讨论】:

                    【解决方案17】:
                    [my_date_picker setValue:[UIColor whiteColor] forKey:@"textColor"];
                    

                    似乎在 ios 13 或更高版本上不起作用,您可以为 UIDatePicker 设置overrideUserInterfaceStyle 属性来确定它是显示白色还是黑色。

                    【讨论】:

                      猜你喜欢
                      • 2021-11-19
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-01-14
                      • 2013-11-14
                      • 2015-01-02
                      • 2014-05-03
                      • 1970-01-01
                      • 2023-04-08
                      相关资源
                      最近更新 更多