显示UIPickerView像键盘一样,没有UITextField

问题描述:

我正在寻找一种方式来呈现UIPickerView当用户点击UIBarButtonItem。设想一下表格视图结果的过滤器。显示UIPickerView像键盘一样,没有UITextField

我知道我可以使用一个UITextField inputView,但这不会是这样的 - 我只有一个UIBarButtonItemUITableView

我已经看到使用UIActionSheet,但它看起来并不自然,特别是在动画显示时。

手动开启和关闭屏幕UIView唯一的选择?

该应用程序仅适用于iOS 6+和iPhone,因此我不需要保持与任何其他版本/成语的兼容性。

+1

请勿使用'UIActionSheet'。您不应该将自己的子视图添加到操作表中。当Apple更改操作表的UI时,许多应用程序都将中断。 – rmaddy 2013-03-18 19:42:06

它可能不是您唯一的选择,但是对UIPickerView进行动画处理应该相对容易。添加选取器视图,使其显示在屏幕底部。当它的时间在动画吧:

[UIView animateWithDuration:0.3 animations:^{ 
    self.datePicker.frame = CGRectMake(0, self.view.bounds.size.height - datePicker.bounds.size.height, datePicker.bounds.size.width, datePicker.bounds.size.height); 
}]; 

而当它的时间来隐藏:

[UIView animateWithDuration:0.3 animations:^{ 
    self.datePicker.frame = CGRectMake(0, self.view.bounds.size.height, datePicker.bounds.size.width, datePicker.bounds.size.height); 
}]; 

一个更好的选择仍然是使用UITextField。你不必在屏幕上实际显示它。只需将它放在0x0 UIView中,以便它不可见,请将其设置为inputView至您的UIPickerView并在其上调用becomeFirstResponder以显示选取器,并且resignFirstResponder将其隐藏。

有一个UIView子类可以很方便地实现所有这些以及UIPickerViewDelegateUIPickerViewDataSource方法。

+0

好主意。你可以添加一些代码吗? – 2016-02-09 14:01:18

+0

@意义事项我添加了一个工作Swift实现作为一个单独的答案。 – CodeMonkey 2016-03-24 20:30:31

我去一个看不见的UITextFieldborisgolovnev的建议,并与下面的雨燕2.3实现想出了:

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就可以方便地使用这样的:

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" 
    } 

} 

希望有人认为这有用=)

附加一个UIPickerView作为添加到视图中的0大小的UITextField的inputView。

 let picker = UIPickerView() 
     picker.dataSource = self 
     picker.delegate = self 

     let dummy = UITextField(frame: CGRectZero) 
     view.addSubview(dummy) 

     dummy.inputView = picker 
     dummy.becomeFirstResponder() 
+1

对于swift3,在let dummy = UITextField中使用CGRect.zero(frame:CGRect.zero) – yehyatt 2017-08-24 10:34:04