在#selector 上快速传递参数 [英] Swift passing parameter on #selector

查看:55
本文介绍了在#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆