Show UIPickerView like a keyboard, without UITextField

后端 未结 6 807
长发绾君心
长发绾君心 2021-02-05 15:56

I\'m looking for a way to present a UIPickerView when the user taps on a UIBarButtonItem. Imagine a filter for the table view results.

I know I

6条回答
  •  悲&欢浪女
    2021-02-05 16:54

    I went with borisgolovnev's suggestion of an invisible UITextField and came up with the following Swift 2.3 implementation:

    import UIKit
    
    class PickerViewPresenter: UITextField {
    
        // MARK: - Initialization
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        init() {
            super.init(frame: CGRect.zero)
        inputView = pickerView
        inputAccessoryView = pickerInputAccessoryView
        }
    
        // MARK: - Public
    
        var pickerDelegate: UIPickerViewDelegate? {
            didSet {
                pickerView.delegate = pickerDelegate
            }
        }
    
        var pickerDataSource: UIPickerViewDataSource? {
            didSet {
                pickerView.dataSource = pickerDataSource
            }
        }
    
        var selectButtonAction: (() -> Void)?
    
        var currentlySelectedRow: Int {
            return pickerView.selectedRowInComponent(0)
        }
    
        func selectRowAtIndex(index: Int) {
            pickerView.selectRow(index, inComponent: 0, animated: false)
        }
    
        func showPicker() {
            self.becomeFirstResponder()
        }
    
        func hidePicker() {
            self.resignFirstResponder()
        }
    
        // MARK: - Views
    
        private let pickerView = UIPickerView(frame: CGRect.zero)
    
        private lazy var pickerInputAccessoryView: UIView = {
            let frame = CGRect(x: 0.0, y: 0.0, width: 0.0, height: 48.0)
            let pickerInputAccessoryView = UIView(frame: frame)
    
            // Customize the view here
    
            return pickerInputAccessoryView
        }()
    
        func selectButtonPressed(sender: UIButton) {
            selectButtonAction?()
        }
    
    }
    

    PickerViewPresenter can then conveniently be used as such:

    class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            view.addSubview(pickerViewPresenter)
        }
    
        private let dataModel = [10, 20, 30, 40, 50]
    
        private lazy var pickerViewPresenter: PickerViewPresenter = {
            let pickerViewPresenter = PickerViewPresenter()
            pickerViewPresenter.pickerDelegate = self
            pickerViewPresenter.pickerDataSource = self
            pickerViewPresenter.selectButtonAction = { [weak self] () -> Void in
                guard let strongSelf = self else {
                    return
                }
                let result = strongSelf.dataModel[pickerViewPresenter.currentlySelectedRow]
                pickerViewPresenter.hidePicker()
                // ...
            }
    
            return pickerViewPresenter
        }()
    
        private func presentPickerView {
            let index = 0 // [0..dataModel.count-1]
            pickerViewPresenter.selectRowAtIndex(index)
            pickerViewPresenter.showPicker()
        }
    
        // MARK: - UIPickerViewDataSource
    
        func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
            return 1
        }
    
        func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return dataModel.count
        }
    
        // MARK: - UIPickerViewDelegate
    
        func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            return "\(dataModel[row]) drunken sailors"
        }
    
    }
    

    Hope someone finds this useful =)

提交回复
热议问题