是否可以在 Swift 中拥有来自同一个 UITextField 的 UIPickerView 和 UIDatePicker?

Posted

技术标签:

【中文标题】是否可以在 Swift 中拥有来自同一个 UITextField 的 UIPickerView 和 UIDatePicker?【英文标题】:Is it possible to have a UIPickerView and a UIDatePicker from the same UITextField in Swift? 【发布时间】:2015-03-30 21:37:15 【问题描述】:

我是 Swift 新手,所以请多多包涵。

首先,让我解释一下我的应用布局:

我在屏幕上有一个文本字段,带有一个标签和一个按钮。我问用户 3 个问题 - 这些问题使用“标签”显示,并且每次用户按下下一个“按钮”时都会出现下一个问题(这些问题是从数组中填充的)。

其中一个问题需要填充选择器视图(以便用户可以选择一个选项)。 其中一个问题使用普通键盘。 最后一个问题我需要使用日期选择器。

这可能吗?如果是这样,你能告诉我如何将它添加到下面的代码中吗?

let questions = ["What is your title?", "What is your full name?", "When were you born?"]

var currentQuestionIndex = 0

let placeholder = ["Title", "Full name", "Date of birth"]

var currentPlaceholderIndex = 0

@IBAction func nextButton(sender: AnyObject) 

    textField.hidden = false
    textField.placeholder = placeholder[currentPlaceholderIndex]
    barImage.hidden = false

    // Reset text field to have no text
    textField.text = ""


    questionLabel.text = questions[currentQuestionIndex]

    // Displays the questions in array
    if currentQuestionIndex < questions.count 
        ++currentQuestionIndex

        // Displays the placeholder text in the textfield
        if currentPlaceholderIndex < placeholder.count 
            ++currentPlaceholderIndex

        

        buttonLabel.setTitle("Next", forState: UIControlState.Normal)


    

    else 

       //Add some logic here to run whenever the user has answered all the questions.

    

  

感谢您的帮助!

尼克

以下新代码(自 2015 年 4 月 6 日起):

类 ViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate

var pickerData = ["Mr", "Mrs", "Miss", "Ms", "Doctor"]

var questions = ["What is your title?", "What is your name?", "What is your DOB?"]

var currentQuestionIndex = 0

var datePickerView:UIDatePicker = UIDatePicker()
var pickerView:UIPickerView = UIPickerView()

@IBOutlet var buttonLabel: UIButton!

@IBOutlet var questionsLabel: UILabel!

@IBOutlet var textField: UITextField!

@IBAction func textFieldEditing(sender: UITextField) 

    datePickerView.datePickerMode = UIDatePickerMode.Date
    sender.inputView = datePickerView
    datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)


func datePickerValueChanged(sender: UIDatePicker) 
    var dateformatter = NSDateFormatter()
    dateformatter.dateStyle = NSDateFormatterStyle.LongStyle
    textField.text = dateformatter.stringFromDate(sender.date)


@IBAction func nextButton(sender: UIButton) 

    textField.text = ""
    textField.hidden = false
    buttonLabel.setTitle("Next", forState: UIControlState.Normal)
    questionsLabel.text = questions[currentQuestionIndex]

    if currentQuestionIndex < questions.count 

        currentQuestionIndex++ 
    

    else 
        //println("questions are complete")
    


func textFieldDidBeginEditing(textField: UITextField) 

    switch currentQuestionIndex 

    case 0:
        self.view.addSubview(datePickerView)

    case 2:
        self.view.addSubview(pickerView)
    default:
        println("Test")
    



override func viewDidLoad() 
    super.viewDidLoad()
    buttonLabel.setTitle("Start", forState: UIControlState.Normal)
    textField.hidden = true
    questionsLabel.text = ""
    textField.delegate = self
    pickerView.delegate = self
    pickerView.dataSource = self


    // 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 textFieldShouldReturn(textField: UITextField) -> Bool 
    textField.resignFirstResponder()
    return true


override func touchesBegan(touches: NSSet, withEvent event: UIEvent) 
    self.view.endEditing(true)




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) 

textField.text = pickerData[row]
pickerView.hidden = true


【问题讨论】:

为您要使用的每个元素制作一个 IBOulet,检查您需要该元素的哪个问题,显示该元素并隐藏其他元素 @Nick89 刚回去看看您是否可以使用该解决方案,但我发现您的代码中存在问题。您确实放入 nextButton(:) 的函数 textFieldDidBeginEditing(:) 应该不在此函数中。 textFieldDidBeginEditing(:) 是在 UITextFieldDelegate 中声明的方法,您已遵守该方法,现在您应该实现它。请记住,协议中声明(未定义)的方法只是抽象的,真正的实现来自您的 ViewController。 @Nick89 如果您有任何问题,请随时告诉我 @user4130613 - 首先感谢您对这一切的帮助!我已经开始了一个新项目,希望能保持整洁。请查看我上面的所有新代码。据我所知,我已经按照您所说的更新了所有内容(我认为!),但它没有按预期工作。我所看到的只是一个 DatePicker 加班,我按下了 textField。我没有看到第一个问题的 pickerView 和第二个问题的键盘......?谢谢 嘿@user4130613 - 我想知道你是否有机会看看上面的内容?谢谢 【参考方案1】:

基于currentQuestionIndex,您可以将UIPickerViewUIDatePicker 添加到您的UITextField 实例中

switch currentQuestionIndex 
case 0: 
  // TODO: Add UIPickerView
case 2:
  // TODO: Add UIDatePicker

编辑:更多解释

首先,符合UITextFieldDelegate并实现textFieldDidBeginEditing(:) 您必须实现该方法,因为您想在 UITextField 实例获得第一响应者状态时得到通知

另外,将UITextField 实例的delegate 属性设置为self 或您想要放置和实现的任何实例/对象textFieldDidBeginEditing(:)

然后写这段代码

func textFieldDidBeginEditing(_ textField: UITextField) 
  switch currentQuestionIndex 
    case 0: 
      // TODO: Add UIPickerView
      // Add it for example at the bottom your view self.view.addSubview(pickerViewInstance)
      // or add it as the subview of UIPopoverController instance that is added to your UITextField instance 
    case 2:
      // TODO: Add UIDatePicker
      // Add it for example at the bottom your view self.view.addSubview(datePickerInstance)
      // or add it as the subview of UIPopoverController instance that is added to your UITextField instance 
  

当您想向 UIPopoverViewController 添加另一个视图时,请记住删除添加的视图。

编辑:添加真实世界的实现

class NewCaseViewController : UIViewController 
    . . .

    @IBOutlet weak var textField: UITextField // TODO: Initialize it properly in designated initializer
    var popoverController: UIPopoverController! // TODO: Initialize it

    . . .



class PopoverContentManager : UIViewController 
    . . .

    var pickerView: UIPickerView // TODO: Initialize it properly
    var datePicker: UIDatePicker // TODO: Initialize it properly

    . . .


extension NewCaseViewController : UITextFieldDelegate 
    func textFieldBeginEditing(_ textField: UITextField) 
        println(__FUNCTION__)

        var popover = PopoverContentManager()

        switch self.currentQuestionIndex 
            case 0:
                popover.datePicker.hidden = true

                self.popoverController = init(contentViewController: popOver)

                self.popoverController.presentPopoverFromRect(self.textField.bounds, inView: self.textField, permittedArrowDirections: UIPopoverArrowDirectionDown, animated: true)

                self.popoverController.popoverContentSize = CGSizeMake(120, 90)
            case 1:
                popover.pickerView.hidden = true

                self.popoverController = init(contentViewController: popOver)

                self.popoverController.presentPopoverFromRect(self.textField.bounds, inView: self.textField, permittedArrowDirections: UIPopoverArrowDirectionDown, animated: true)

                self.popoverController.popoverContentSize = CGSizeMake(120, 90)
            
        

【讨论】:

感谢 user4130613,我在上面添加了更多信息,因为我遇到了一些错误...谢谢 对不起,我仍然遇到问题,并且真的很想了解我哪里出错了。我在上面的问题中添加了我的新代码,所以你可以看到我的所有代码。我收到一条错误消息,提示“使用未解析的标识符“pickerViewInstance”和“datePickerInstance”。我非常感谢您帮助我理解我做错了什么,因为我对这一切都很陌生,并且很想了解它!提前致谢 @Nick89 这是因为你没有在 ViewController 类中定义 pickerViewInstance 和 datePickerInstance 所以定义它们并在 ViewController 中初始化它们

以上是关于是否可以在 Swift 中拥有来自同一个 UITextField 的 UIPickerView 和 UIDatePicker?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Swift 3 显示来自核心数据的随机数据

Swift 中的 AWS Cognito getSession 导致来自 API GW 的 401 未授权

是否可以在工件中拥有本地 git 存储库?

UITableView 部分中的 NSDates 不反映来自 UIDatePicker 的日期

检测是不是在 UITextField 中输入了“空格”,并移动到下一个 UITextField

在 uiview 中有超过 1 个 uitextfield 的 iOS swift 委托