Set text color and font for UIDatePicker in iOS8/Swift
Solution 1
Changing the date mode to something else seems to force a re-draw with the newly set text color.
datePicker.setValue(UIColor.whiteColor(), forKeyPath: "textColor")
datePicker.datePickerMode = .CountDownTimer
datePicker.datePickerMode = .DateAndTime //or whatever your original mode was
Solution 2
you just need to set 2 lines of code in viewdidLoad
/ viewWillAppear
accoding where you using DatePicker.
dobDatePicker.setValue(UIColor.whiteColor(), forKeyPath: "textColor")
dobDatePicker.setValue(false, forKey: "highlightsToday")
See the Result like this:
Solution 3
The only way for changing the font of UIDatePickerView (until now) is swizzling:
you can change the font by an extension of UILabel! (this is not recommended but it works!)
import Foundation
import UIKit
public extension UILabel {
@objc func setFontSwizzled(font: UIFont) {
if self.shouldOverride() {
self.setFontSwizzled(font: <THE UIFont FOR ALL DATEPICKERS!>)
} else {
self.setFontSwizzled(font: font)
}
}
private func shouldOverride() -> Bool {
let classes = ["UIDatePicker", "UIDatePickerWeekMonthDayView", "UIDatePickerContentView"]
var view = self.superview
while view != nil {
let className = NSStringFromClass(type(of: view!))
if classes.contains(className) {
return true
}
view = view!.superview
}
return false
}
private static let swizzledSetFontImplementation: Void = {
let instance: UILabel = UILabel()
let aClass: AnyClass! = object_getClass(instance)
let originalMethod = class_getInstanceMethod(aClass, #selector(setter: font))
let swizzledMethod = class_getInstanceMethod(aClass, #selector(setFontSwizzled))
if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod {
// switch implementation..
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}()
static func swizzleSetFont() {
_ = self.swizzledSetFontImplementation
}
}
and for changing the color you just simply call the function below:
datePicker.setValue(UIColor.whiteColor(), forKeyPath: "textColor")
if it's necessary to be re-rendered you need to call:
datePicker.datePickerMode = .CountDownTimer
datePicker.datePickerMode = .DateAndTime //or whatever your original mode was
Solution 4
I believe this is the definitive solution for countdown timers.
It's an expansion of yildirimosman's answer.
//text color
datePicker.setValue(UIColor.whiteColor(), forKey: "textColor")
//picker background
datePicker.subviews[0].subviews[0].backgroundColor = UIColor.clearColor() //the picker's own background view
//dividers
datePicker.subviews[0].subviews[1].backgroundColor = UIColor.whiteColor()
datePicker.subviews[0].subviews[2].backgroundColor = UIColor.whiteColor()
//labels: "hours" and "min"
datePicker.subviews[0].subviews[3].setValue(UIColor.lightGrayColor(), forKey: "textColor")
datePicker.subviews[0].subviews[4].setValue(UIColor.lightGrayColor(), forKey: "textColor")
//refresh the tableview (to force initial row textColor to change to white)
datePicker.subviews[0].setNeedsLayout()
datePicker.subviews[0].layoutIfNeeded()
Solution 5
you can use
datePicker.setValue(UIColor.whiteColor(), forKey: "textColor")
datePicker.setValue(false, forKey: "highlightsToday")
//for selector color
datePickerView.subviews[0].subviews[1].backgroundColor = UIColor.whiteColor()
datePickerView.subviews[0].subviews[2].backgroundColor = UIColor.whiteColor()
Fenda
Updated on September 08, 2021Comments
-
Fenda almost 3 years
I've been having trouble trying to set the
UIDatePicker
font and color. Everything else in my app was fairly straightforward to adjust except this. Does anybody know how to do this? I'm using Swift for iOS8. -
villy393 over 8 yearsI can't believe this is something we need to hack with
setValue forKeypath
. Its not like we are trying to replace the the date values with emoji's or something random. -
Michael over 8 yearsThis will change the background color of the picker itself, not the font of color of the font. Personally, I think it would make this guys design look terrible.
-
Klemen over 8 yearsThis is the best answer. I try many of them an this one works and dont corrupt Today label in picker.
-
Alsop about 8 yearsI should note that I am using the compare extensions found here: stackoverflow.com/questions/26198526/…
-
ObjectiveTC almost 8 yearsSee my other answer for expanded solution.
-
Markinson over 7 yearsThis is what I needed man. But unfortunately your post was so far down here that I had to find it somewhere else. Hopefully more people see it earlier
-
Supertecnoboff about 6 yearsFor anything else a replica would be fine, but for dates?! Surely not - as we know there are so many things that can go wrong when an indie dev tries to mess around with dates on their own - timezone changes, daylight savings, etc.... The UIDatePicker takes care of all that and provides a reliable NSDate object. It's just a shame that it doesn't have some basic customisation options.
-
gohnjanotis almost 6 yearsThis approach causes a crash if the UIDatePicker is being used when the mode is switched.
-
sudoExclaimationExclaimation about 5 yearsThis is the only solution which worked for font changing! Bravo! Here's the order to call the functions:
let datePicker = UIDatePicker() UILabel.swizzleSetFont() datePicker.setValue(themeMacro(themeKey: "titleColor"), forKey: "textColor") datePicker.datePickerMode = .date
-
Anthony over 4 yearsThanks for actually answering the question asked. Thank you
-
Evan R almost 4 years@ScottyBlades You can get access to the main dispatch queue from any function; that's not why this code needs to go there (if indeed it does—I haven't tested it). If the answer is correct, it needs to go there because of the order of
UIKit
's view lifecycle forUIViewController
. -
karthikeyan over 3 yearsnot able to call this method... How to use this?