gpt4 book ai didi

swift - 如何使用 UIDatePicker 输入管理带有两个 UITextField 的 firstResponder

转载 作者:行者123 更新时间:2023-11-28 07:26:08 26 4
gpt4 key购买 nike

我有一个 ViewController 和两个使用 UIDatePicker(s) 进行输入的 UITextFields。一个是“开始”日期,另一个是“结束”日期,因此这似乎是一种相当常见的情况。

问题在于,当一个字段的 DatePicker 处于事件状态时,用户可能会点击屏幕上的另一个字段。事件的 DatePicker 仍然绑定(bind)到第一个字段,因此 UI 会让用户感到困惑,因为光标在另一个字段中闪烁,但输入不在那里。

我认为正确的 UI 解决方案是防止用户点击任何其他字段,直到 DatePicker 被关闭。但是我无法找到一种方法来检测 firstResponder 正在更改或暂时禁用对其他字段的编辑。

这是我当前的代码,它没有做我需要它做的事情:

class AddTripLocationVC: UIViewController, UITextFieldDelegate {

@IBOutlet private weak var tripLocFromDateInput: UITextField!
@IBOutlet private weak var tripLocToDateInput: UITextField!

override func viewDidLoad() {
super.viewDidLoad()

//set up datepickers for text field inputs
createDatePicker(forDateField: tripLocFromDateInput)
createDatePicker(forDateField: tripLocToDateInput)

}

//automatically update the label fields when the date vairables are updated by the UIDatePicker
var locFromDate: Date? {
didSet {
guard locFromDate != nil else { return }
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MMM yyyy"
tripLocFromDateInput.text = dateFormatter.string(from: locFromDate!)
}
}

var locToDate: Date? {
didSet {
guard locToDate != nil else { return }
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MMM yyyy"
tripLocFromDateInput.text = dateFormatter.string(from: locToDate!)
//Comment after solution found...The problem was the line above
//It should be:
tripLocToDateInput.text = dateFormatter.string(from: locToDate!)
}
}

func createDatePicker(forDateField dateField: UITextField) {

let datePickerView = UIDatePicker()
datePickerView.datePickerMode = .date
dateField.inputView = datePickerView
datePickerView.addTarget(self, action: #selector(handleDatePicker(sender:)), for: .valueChanged)

let doneButton = UIBarButtonItem.init(title: "Done", style: .done, target: self, action: #selector(self.datePickerDone))
let toolBar = UIToolbar.init(frame: CGRect(x: 0, y: 0, width: view.bounds.size.width, height: 44))
toolBar.setItems([UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil), doneButton],
animated: true)
dateField.inputAccessoryView = toolBar
}

@objc
func handleDatePicker(sender: UIDatePicker) {

if tripLocFromDateInput.isFirstResponder {
locFromDate = sender.date
} else {
if tripLocToDateInput.isFirstResponder {
locToDate = sender.date
} else {
print("Error: Can't find first responder field.")
}
}
}

@objc
func datePickerDone(dateField: UITextView) {

if tripLocFromDateInput.isFirstResponder {
tripLocFromDateInput.resignFirstResponder()
} else {
if tripLocToDateInput.isFirstResponder {
tripLocToDateInput.resignFirstResponder()
} else {
print("Error: Can't find first responder field.")
}
}
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}

func textFieldDidEndEditing(_ textField: UITextField) {
textField.becomeFirstResponder()
}
}

对于 iOS 中这种类型的“从”和“到”日期字段,UI 是否有“标准”方法?

最佳答案

您可以注册一个 UITextField 委托(delegate),其中包含您特别感兴趣的两个方法,特别是:

  • textFieldDidBeginEditing(:)
  • textFieldDidEndEditing(:)

要获取更多信息,请访问:https://developer.apple.com/documentation/uikit/uitextfielddelegate

请注意,您还可以在任何 UITextField 上使用 becomeFirstResponder() 来激活它。无论哪个处于事件状态,都应该有闪烁的光标。


编辑:根据您更新的代码:

//
// ViewController.swift
// datepickers
//
// Created by Dave Poirier on 2019-06-13.
//

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet private weak var tripLocFromDateInput: UITextField!
@IBOutlet private weak var tripLocToDateInput: UITextField!

override func viewDidLoad() {
super.viewDidLoad()

//set up datepickers for text field inputs
createDatePicker(forDateField: tripLocFromDateInput)
createDatePicker(forDateField: tripLocToDateInput)

//set text field delegates to be notified when focus changes
tripLocFromDateInput.delegate = self
tripLocToDateInput.delegate = self
}


func createDatePicker(forDateField dateField: UITextField) {

let datePickerView = UIDatePicker()
datePickerView.datePickerMode = .date
dateField.inputView = datePickerView
datePickerView.addTarget(self, action: #selector(handleDatePicker(sender:)), for: .valueChanged)

let doneButton = UIBarButtonItem.init(title: "Done", style: .done, target: self, action: #selector(self.datePickerDone))
let toolBar = UIToolbar.init(frame: CGRect(x: 0, y: 0, width: view.bounds.size.width, height: 44))
toolBar.setItems([UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil), doneButton],
animated: true)
dateField.inputAccessoryView = toolBar
}

@objc
func handleDatePicker(sender: UIDatePicker) {

if tripLocFromDateInput.isFirstResponder {
let locFromDate = sender.date
tripLocFromDateInput.text = "FROM: \(locFromDate)"
} else {
if tripLocToDateInput.isFirstResponder {
let locToDate = sender.date
tripLocToDateInput.text = "TO: \(locToDate)"
} else {
print("Error: Can't find first responder field.")
}
}
}

@objc
func datePickerDone(dateField: UITextView) {

if tripLocFromDateInput.isFirstResponder {
tripLocFromDateInput.resignFirstResponder()
} else {
if tripLocToDateInput.isFirstResponder {
tripLocToDateInput.resignFirstResponder()
} else {
print("Error: Can't find first responder field.")
}
}
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
self.view.endEditing(true)
}
}

}

上面的代码在一个全新的项目中为我工作,创建了两个输入字段并连接了 IBOutlets

关于swift - 如何使用 UIDatePicker 输入管理带有两个 UITextField 的 firstResponder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56573091/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com