Try using the following class. I subclassed UIPickerView and pointed colors inside. This is working fine. when you install items. he will install the delegate and data source himself and do the work for you.
import UIKit class CustomUIPickerView: UIPickerView{ let textColor: UIColor = .white let backGroundColor: UIColor = .blue let _tintColor: UIColor = .white var items: [String]?{ didSet{ self.delegate = self self.dataSource = self self.reloadAllComponents() } } override init(frame: CGRect) { super.init(frame: frame) commonInit() } func commonInit(){ self.backgroundColor = backGroundColor self.tintColor = _tintColor } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } } extension CustomUIPickerView: UIPickerViewDataSource{ func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return self.items?.count ?? 0 } } extension CustomUIPickerView: UIPickerViewDelegate{ func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { let string = self.items?[row] ?? "" return NSAttributedString(string: string, attributes: [NSAttributedStringKey.foregroundColor: textColor]) } }
However, if you want to handle the delegate and data source in the view controller, you can take advantage of the use of Extensions , here's how:
extension String{ func stringForPickerView() -> NSAttributedString{ let color: UIColor = .white return NSAttributedString(string: self, attributes: [NSAttributedStringKey.foregroundColor: color]) } }
then in your ViewController:
extension ViewController: UIPickerViewDelegate{ func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { return self.items[row].stringForPickerView()
source share