Skip to content

Instantly share code, notes, and snippets.

@auramagi
Created February 18, 2019 16:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save auramagi/0768176ea34e4d3b9e1005b999153a55 to your computer and use it in GitHub Desktop.
Save auramagi/0768176ea34e4d3b9e1005b999153a55 to your computer and use it in GitHub Desktop.
Present UIPicker on a UILabel to select from a few options. Supports a placeholder value. For this example the picker selects a weekday.
import UIKit
enum Weekday: Int {
case monday = 1
case tuesday = 2
case wednesday = 3
case thursday = 4
case friday = 5
case saturday = 6
case sunday = 0
var string: String {
return Calendar.current.standaloneWeekdaySymbols[rawValue]
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let label = PickerLabel(frame: .zero)
view.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor)
]
NSLayoutConstraint.activate(constraints)
//// Pre-set the selected option here like this:
// label.selectedOption = .friday
}
}
class PickerLabel: UIControl {
var selectedOption: Weekday? = nil {
didSet { updateLabel() }
}
var labelPlaceholder: String = "Select me!" {
didSet { updateLabel() }
}
private let pickerOptions: [Weekday?] = [nil, .monday, .tuesday, .wednesday, .thursday, .friday, .saturday, .sunday]
private let pickerPlaceholder = ""
private let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup() {
addTarget(self, action: #selector(presentPicker), for: .touchUpInside)
addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
label.topAnchor.constraint(equalTo: topAnchor),
label.bottomAnchor.constraint(equalTo: bottomAnchor),
label.leadingAnchor.constraint(equalTo: leadingAnchor),
label.trailingAnchor.constraint(equalTo: trailingAnchor)
]
NSLayoutConstraint.activate(constraints)
label.textAlignment = .center
updateLabel()
}
func updateLabel() {
if let selectedOption = selectedOption {
label.text = selectedOption.string
} else {
label.text = labelPlaceholder
}
}
// The picker itself
private lazy var _inputView: UIView = {
let pickerView = UIPickerView()
pickerView.delegate = self
let row = pickerOptions.firstIndex(of: selectedOption)!
pickerView.selectRow(row, inComponent: 0, animated: true)
return pickerView
}()
// Toolbar
private lazy var _inputAccessoryView: UIView = {
let toolbar = UIToolbar()
toolbar.items = [
UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissPicker)),
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)]
toolbar.autoresizingMask = [.flexibleHeight, .flexibleWidth]
return toolbar
}()
@objc func presentPicker() {
becomeFirstResponder()
label.textColor = .red
}
@objc func dismissPicker() {
resignFirstResponder()
label.textColor = .black
}
// Implementation for UIControl methods
override var canBecomeFirstResponder: Bool { return true }
override var inputView: UIView? { return _inputView }
override var inputAccessoryView: UIView? { return _inputAccessoryView }
}
extension PickerLabel: UIPickerViewDataSource {
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerOptions.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
}
extension PickerLabel: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if let option = pickerOptions[row] {
return option.string
}
return pickerPlaceholder
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedOption = pickerOptions[row]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment