如何使用完成按钮制作 UIPickerView?

Posted

技术标签:

【中文标题】如何使用完成按钮制作 UIPickerView?【英文标题】:How to make an UIPickerView with a Done button? 【发布时间】:2015-07-30 15:58:59 【问题描述】:

当用户点击 UITextField 时,我很难制作带有完成按钮的 UIPickerView。到目前为止,这是我的代码。一切正常,但是当我点击文本字段时,出现的是键盘,而不是选择器。

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate 


@IBOutlet var textField1: UITextField!

let pickerData = ["11", "12", "13"]





@IBAction func textButton(sender: AnyObject) 

    let picker: UIPickerView
    picker = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 300))
    picker.backgroundColor = .whiteColor()

    picker.showsSelectionIndicator = true
    picker.delegate = self
    picker.dataSource = self

    let toolBar = UIToolbar()
    toolBar.barStyle = UIBarStyle.Default
    toolBar.translucent = true
    toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
    toolBar.sizeToFit()

    let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")
    let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
    let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")

    toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
    toolBar.userInteractionEnabled = true

    textField1.inputView = picker
    textField1.inputAccessoryView = toolBar








override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int 
    return 1


func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
    return pickerData.count


func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
    return pickerData[row]


func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    textField1.text = pickerData[row]


func donePicker() 

    textField1.resignFirstResponder()







【问题讨论】:

你在哪里调用 textButton 方法? 【参考方案1】:

将此代码添加到您的 viewDidLoad() 而不是方法中

let picker: UIPickerView
picker = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 300))
picker.backgroundColor = .whiteColor()

picker.showsSelectionIndicator = true
picker.delegate = self
picker.dataSource = self

let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
toolBar.sizeToFit()

let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: self, action: #selector(self. donePicker))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItem.Style.plain, target: self, action: #selector(self. donePicker))

toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true

textField1.inputView = picker
textField1.inputAccessoryView = toolBar

【讨论】:

它可能用于不同的线程。但是当我使用上面的示例完成时,没有选择 uipickerview 项目。我该怎么做? @iAnurag 我想在点击按钮时显示选择器,并在从选择器中选择后将其分配给按钮标题。所以 inputAccessoryView 不适用于 UIButton。还有其他解决方案吗? 工具栏右侧的按钮可以对齐吗? 找到解决方案,将以下内容添加为第一项:let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil) 如果你能更新你对 swift 4 或 5 的答案,那就太好了【参考方案2】:

我认为最好创建一个自定义类来从控制器中删除代码。

Swift 4/5 示例

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()
    

用法示例:

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()
    

【讨论】:

didTapDonedidTapCancel 方法最好传入ToolbarPickerView 实例;喜欢func didTapDone(_ picker: ToolbarPickerView)【参考方案3】:

带有完成按钮的 UIPickerView? Swift4

第一步:在 ViewController 中添加一个名为 txt_pickUpData 的 textFiled 并给 IBOutlet 连接和委托。还取一个 UIDatePicker 变量。并获取一个带有字符串值的数组,该数组显示在选择轮上。

@IBOutlet weak var txt_pickUpData: UITextField!
var myPickerView : UIPickerView!
var pickerData = ["Hitesh Modi" , "Kirit Modi" , "Ganesh Modi" , "Paresh Modi"]

第 2 步:同时添加 UIPickerView 和 UITextFiled 的委托。

class ViewController: UIViewController , UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate

第 3 步:函数 pickUp 使用 ToolBar 创建 UIPickerView。

func pickUp(_ textField : UITextField)

// UIPickerView
self.myPickerView = UIPickerView(frame:CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 216))
self.myPickerView.delegate = self
self.myPickerView.dataSource = self
self.myPickerView.backgroundColor = UIColor.white
textField.inputView = self.myPickerView

// ToolBar
let toolBar = UIToolbar()
toolBar.barStyle = .default
toolBar.isTranslucent = true
toolBar.tintColor = UIColor(red: 92/255, green: 216/255, blue: 255/255, alpha: 1)
toolBar.sizeToFit()

// Adding Button ToolBar
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ViewController.doneClick))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(ViewController.cancelClick))
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
textField.inputAccessoryView = toolBar

 

第四步:添加 UIPickerView 的委托和数据源方法,在 UIPickerView 轮上显示数据。

//MARK:- PickerView Delegate & DataSource
func numberOfComponents(in pickerView: UIPickerView) -> Int 
return 1
 
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
return pickerData.count
 
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
return pickerData[row]
  
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
self.txt_pickUpData.text = pickerData[row]
 
 //MARK:- TextFiled Delegate

 func textFieldDidBeginEditing(_ textField: UITextField) 
self.pickUp(txt_pickUpData)
 

步骤 5:添加两个按钮方法,在 ToolBar 中。一个是doneClick,另一个是cancelClick。这是关闭 UIPickerView。

@objc func doneClick() 
  txt_pickUpData.resignFirstResponder()
 
@objc func cancelClick() 
  txt_pickUpData.resignFirstResponder()

第 6 步:在 UITextField 委托方法中调用 pickUp 函数。

func textFieldDidBeginEditing(_ textField: UITextField) 
self.pickUp(txt_pickUpData)

只需复制并粘贴到您的代码中。

【讨论】:

请注意,在 Swift 4 中,您需要在 doneClickcancelClick 函数前添加 @objc 感谢您如此完整的回答!我还注意到,我们应该记住将 ViewController 设置为 textField 委托 - txt_pickUpData.delegate = self。我做了故事板 您也可以为操作添加#selector()【参考方案4】:

人们似乎在使用此处的代码来解决其他问题,以提出与 VBaarathi 相同的问题

在 Swift3 中

let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(donePicker))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(donePicker))

然后你可以将以下内容放在同一个 swift 文件中

func donePicker (sender:UIBarButtonItem)

     // Put something here

【讨论】:

【参考方案5】:

Swift 3x:

已经给出了很棒的答案,但这里有不同的方法,只需创建一个 pickerView 并像这样给出 inputViewinputAccessoryView

YOUR_TEXTFIELD_NAME.inputView = picker


func addKeyboardToolBar() 

  var nextButton: UIBarButtonItem?
  var keyboardToolBar = UIToolbar(frame: CGRect(x: CGFloat(0), y: 
  CGFloat(0), width: CGFloat(pickerView.frame.size.width), height: CGFloat(25)))
  keyboardToolBar.sizeToFit()
  keyboardToolBar.barStyle = .default
  daysHourTextField.inputAccessoryView = keyboardToolBar
  nextButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.textFieldShouldReturn))
  keyboardToolBar.items = [UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil), nextButton]


【讨论】:

【参考方案6】:

使用 IQKeyboardManager 库。设置完成后,它会自动为您添加完成按钮。在这里查看:github

首先安装 pod

pod 'IQKeyboardManagerSwift'

然后在 AppDelegate.swift 中,只需导入 IQKeyboardManagerSwift 框架并启用 IQKeyboardManager。

 import IQKeyboardManagerSwift

 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate 

   var window: UIWindow?

   func application(_ application: UIApplication, 
    didFinishLaunchingWithOptions launchOptions: 
    [UIApplication.LaunchOptionsKey: Any]?) -> Bool 

    IQKeyboardManager.shared.enable = true

    return true
  

此库会自动为您在键盘中添加完成按钮。

【讨论】:

以上是关于如何使用完成按钮制作 UIPickerView?的主要内容,如果未能解决你的问题,请参考以下文章

使用 UIToolBar 上的完成按钮关闭 UIPickerView

如何在uipickerview上添加完成按钮

如何将带有完成按钮的工具栏添加到 UIPickerView?

在 UITableView 中隐藏 UIPickerview 完成按钮

如何制作windows10安装u盘

如何以编程方式在按钮点击时隐藏 UIPickerview?