在#selector 上快速传递参数 [英] Swift passing parameter on #selector
问题描述
如何使用相同的函数在 2 个不同的文本字段上处理 DatePickerView?
为了避免重复,我想用 DatePicker 设置 2 个 textField.一个字段用于发布日期,另一个字段用于到期日期.
To avoid repetition, I would like to set up 2 textFields with a DatePicker. One field is for issue date and the other one for due date.
当我尝试在@objc func doneClick 上添加参数时,出现编译器错误==> 实例成员doneClick"不能用于类型InvoiceViewController";您是想改用这种类型的值吗?
When I try to add parameter on @objc func doneClick, I got a compiler error ==> Instance member 'doneClick' cannot be used on type 'InvoiceViewController'; did you mean to use a value of this type instead?
import UIKit
class InvoiceViewController: UIViewController, UITextFieldDelegate{
var thePicker = UIDatePicker()
@IBOutlet weak var dateIssueTextField: UITextField!
@IBOutlet weak var dueDateTextField: UITextField!
@objc func doneClick(textField: UITextField!) {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .none
dateIssueTextField.text = dateFormatter.string(from: thePicker.date)
dateFormatter.dateFormat = "yyyy"
let year: String = dateFormatter.string(from: self.thePicker.date)
dateFormatter.dateFormat = "MM"
let month: String = dateFormatter.string(from: self.thePicker.date)
dateFormatter.dateFormat = "dd"
let day: String = dateFormatter.string(from: self.thePicker.date)
let finalDate = year+"-"+month+"-"+day
print(finalDate)
// dateIssueTextField.resignFirstResponder()
textField.resignFirstResponder()
}
@objc func cancelClick() {
dateIssueTextField.resignFirstResponder()
}
func setUpTextFieldPicker(textField: UITextField) {
// DatePicker
self.thePicker = UIDatePicker(frame:CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 216))
self.thePicker.backgroundColor = UIColor.white
self.thePicker.datePickerMode = UIDatePickerMode.date
// dateIssueTextField.inputView = thePicker
// dueDateTextField.inputView = thePicker
textField.inputView = thePicker
// 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(InvoiceViewController.doneClick))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(InvoiceViewController.cancelClick))
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
//dateIssueTextField.inputAccessoryView = toolBar
//dueDateTextField.inputAccessoryView = toolBar
textField.inputAccessoryView = toolBar
}
override func viewDidLoad() {
super.viewDidLoad()
setUpTextFieldPicker(textField: dateIssueTextField)
setUpTextFieldPicker(textField: dueDateTextField)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
推荐答案
doneClick
不能有 UITextField
类型的参数,当它用作 UIBarButtonItem 的目标时代码>.
doneClick
cannot have parameter of UITextField
type, when it's used as a target to UIBarButtonItem
.
您将不得不编辑的不仅仅是该方法.工具栏需要知道它属于哪个 UITextField
.因此,创建 UIToolbar
的自定义子类,您将在其中设置其项目,并向其添加一个委托,该委托将在完成和取消按下时发送事件:
You will have to edit more than just that method. The toolbar needs to know to which UITextField
it belongs to. So create your custom subclass of UIToolbar
, in which you will setup its items, and add a delegate to it which will be sent events on done and cancel pressed:
import UIKit
protocol AccessoryToolbarDelegate: class {
func doneClicked(for textField: UITextField)
func cancelClicked(for textField: UITextField)
}
class AccessoryToolbar: UIToolbar {
fileprivate let textField: UITextField
weak var accessoryDelegate: AccessoryToolbarDelegate?
init(for textField: UITextField) {
self.textField = textField
super.init(frame: CGRect.zero)
self.barStyle = .default
self.isTranslucent = true
self.tintColor = UIColor(red: 92/255, green: 216/255, blue: 255/255, alpha: 1)
self.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneClicked))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelClicked))
self.setItems([cancelButton, spaceButton, doneButton], animated: false)
self.isUserInteractionEnabled = true
textField.inputAccessoryView = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc fileprivate func doneClicked() {
accessoryDelegate?.doneClicked(for: self.textField)
}
@objc fileprivate func cancelClicked() {
accessoryDelegate?.cancelClicked(for: self.textField)
}
}
现在使用此代码,您可以将旧代码重写为:
Now with this code you can rewrite your old code to:
import UIKit
class InvoiceViewController: UIViewController, AccessoryToolbarDelegate {
var thePicker = UIDatePicker()
@IBOutlet weak var dateIssueTextField: UITextField!
@IBOutlet weak var dueDateTextField: UITextField!
func doneClicked(for textField: UITextField) {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .none
// I am not sure if you want this
textField.text = dateFormatter.string(from: thePicker.date)
// or rather this, but that's up to you to finish
dateFormatter.dateFormat = "yyyy-MM-dd"
let finalDate: String = dateFormatter.string(from: thePicker.date)
print(finalDate)
textField.resignFirstResponder()
}
func cancelClicked(for textField: UITextField) {
textField.resignFirstResponder()
}
func setUpTextFieldPicker(textField: UITextField) {
// DatePicker
self.thePicker = UIDatePicker(frame:CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 216))
self.thePicker.backgroundColor = UIColor.white
self.thePicker.datePickerMode = UIDatePickerMode.date
// dateIssueTextField.inputView = thePicker
// dueDateTextField.inputView = thePicker
textField.inputView = thePicker
// ToolBar
let toolbar = AccessoryToolbar(for: textField)
// let's not forget to set the delegate
toolbar.accessoryDelegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
setUpTextFieldPicker(textField: dateIssueTextField)
setUpTextFieldPicker(textField: dueDateTextField)
}
}
这篇关于在#selector 上快速传递参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!