How to make an UIPickerView with a Done button?

前端 未结 5 1831
天涯浪人
天涯浪人 2020-12-22 16:31

I am having difficulties to make an UIPickerView with a done button to appear when the users taps a UITextField. This is my code so far. Everything builds fine, but when I t

5条回答
  •  死守一世寂寞
    2020-12-22 17:20

    I think it's better to make a custom class to remove code from controller.

    Swift 4/5 example:

    import Foundation
    import UIKit
    
    protocol ToolbarPickerViewDelegate: class {
        func didTapDone()
        func didTapCancel()
    }
    
    class ToolbarPickerView: UIPickerView {
    
        public private(set) var toolbar: UIToolbar?
        public weak var toolbarDelegate: ToolbarPickerViewDelegate?
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.commonInit()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            self.commonInit()
        }
    
        private func commonInit() {
            let toolBar = UIToolbar()
            toolBar.barStyle = UIBarStyle.default
            toolBar.isTranslucent = true
            toolBar.tintColor = .black
            toolBar.sizeToFit()
    
            let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.doneTapped))
            let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
            let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelTapped))
    
            toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
            toolBar.isUserInteractionEnabled = true
    
            self.toolbar = toolBar
        }
    
        @objc func doneTapped() {
            self.toolbarDelegate?.didTapDone()
        }
    
        @objc func cancelTapped() {
            self.toolbarDelegate?.didTapCancel()
        }
    }
    

    Usage example:

    class MyViewController: UIViewController {
    
        @IBOutlet weak var textField: UITextField!
        fileprivate let pickerView = ToolbarPickerView()
        fileprivate let titles = ["0", "1", "2", "3"]
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.textField.inputView = self.pickerView
            self.textField.inputAccessoryView = self.pickerView.toolbar
    
            self.pickerView.dataSource = self
            self.pickerView.delegate = self
            self.pickerView.toolbarDelegate = self
    
            self.pickerView.reloadAllComponents()
        }
    }
    
    extension MyViewController: UIPickerViewDataSource, UIPickerViewDelegate {
    
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return self.titles.count
        }
    
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
    
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            return self.titles[row]
        }
    
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            self.textField.text = self.titles[row]
        }
    }
    
    extension MyViewController: ToolbarPickerViewDelegate {
    
        func didTapDone() {
            let row = self.pickerView.selectedRow(inComponent: 0)
            self.pickerView.selectRow(row, inComponent: 0, animated: false)
            self.textView.text = self.titles[row]
            self.textField.resignFirstResponder()
        }
    
        func didTapCancel() {
            self.textField.text = nil
            self.textField.resignFirstResponder()
        }
    }
    

提交回复
热议问题