How to change the line color of a UIDatePicker

2020-07-11 06:19发布

I have got a UIDatePicker in one of my ViewControllers. As you can see, the background is dark.

Image of my UIDatePicker

What i already managed to change is the text color to white. What i just can't change is the color of the two lines above and below the selected date. It always remains default dark grey. Does anyone have a code snipped to achieve coloring these lines?

5条回答
\"骚年 ilove
2楼-- · 2020-07-11 06:24

To start with, Apple docs says, about Date Pickers, "You cannot customize the appearance of date pickers."

That being said, the following code does exactly what you need. I understand it's not the most elegant piece of code, but here it is

datePicker.subviews[0].subviews[1].backgroundColor = UIColor.redColor()
datePicker.subviews[0].subviews[2].backgroundColor = UIColor.redColor()

UIDatePicker has a subview, UIDatePickerView, which has 3 subviews, 2 of the latter of which are the two lines that indicate the selection row.

查看更多
Rolldiameter
3楼-- · 2020-07-11 06:28

I had to change height constraint for datePicker and cus of this @kex code didn't worked for me. so I modified it: (works for me on swift 5 and iOS 12)

if let _pickerView = self.datePicker.subviews.first {
    for _subview in _pickerView.subviews {
        if (_subview.backgroundColor != nil) {
            _subview.backgroundColor = UIColor.white
            _subview.tintColor = UIColor.white
            _subview.layer.borderColor = UIColor.white.cgColor
            _subview.layer.borderWidth = 1
        }
    }
}
查看更多
Juvenile、少年°
4楼-- · 2020-07-11 06:42

huniser_suraj answer is correct, just use additional check for future changes, this is how I use it, for UIPickerView & UIDatePicker, respectively:

    for subview in self.picker.subviews {

        if subview.frame.height == 1 {

            subview.backgroundColor = UIColor.whiteColor()
        }
    }

    if let pickerView = self.datePicker.subviews.first {

        for subview in pickerView.subviews {

            if subview.frame.height == 1 {

                subview.backgroundColor = UIColor.whiteColor()
            }
        }
    }

iOS 10 UPDATE

From iOS 10 on, this doesn't work anymore, as mentioned in some of the comments, i.e. finding the subviews & getting to them works, but setting the background color doesn't work anymore. I did another dirty solution for this, I'm setting a border with a border color which works.

    for subview in self.picker.subviews {

        if subview.frame.height <= 5 {

            subview.backgroundColor = UIColor.white
            subview.tintColor = UIColor.white
            subview.layer.borderColor = UIColor.white.cgColor
            subview.layer.borderWidth = 0.5            }
    }

    if let pickerView = self.datePicker.subviews.first {

        for subview in pickerView.subviews {

            if subview.frame.height <= 5 {

                subview.backgroundColor = UIColor.white
                subview.tintColor = UIColor.white
                subview.layer.borderColor = UIColor.white.cgColor
                subview.layer.borderWidth = 0.5
            }
        }
        self.datePicker.setValue(UIColor.white, forKey: "textColor")
    }
查看更多
冷血范
5楼-- · 2020-07-11 06:45

It can be done in a pretty simple way with IB. Just put 2 UiView with height=1, equal width as UIDatePicker. Then center it with UIDatePicker vertically and horizontally. For upper line, set vertical offset to 18, and the other one set to -18. Done!

查看更多
Viruses.
6楼-- · 2020-07-11 06:47

Yes, this is an unsafe method. But as an option, why not.

 if #available(iOS 13.0, *) {
    datePicker.setValue(UIColor.red, forKey: "magnifierLineColor")
    }

More safer solution:

extension UIView {

 func findViews<T: UIView>(subclassOf: T.Type) -> [T] {
    return recursiveSubviews.compactMap { $0 as? T }
 }

 var recursiveSubviews: [UIView] {
    return subviews + subviews.flatMap { $0.recursiveSubviews }
 }

}

self.datePicker.findViews(subclassOf: UIView.self)
            .makeIterator()
            .lazy
            .filter({$0.bounds.height <= 1 && $0.bounds.width == self.datePicker.bounds.width})
            .prefix(2)
            .forEach({$0.backgroundColor = UIColor.red})
查看更多
登录 后发表回答