背景
我必须在我的整个应用中创建一些日期时间选择器,因此我在考虑创建一个 Utility 类,该类将返回可重复使用的UIDateTimePicker
我将在整个应用程序中使用。每个选择器在工具栏
问题 对于点击 Cancel 和 Done 时应该执行的操作,我正在考虑使用如下闭包:
func createDatePicker(isDateTime: Bool, doneAction: ()->(), cancelAction: ()->()) -> UIDatePicker {
// Code for setting up the dateTime picker
// Deciding the picker mode for the picker
dateTimePicker.datePickerMode = isDateTime ? UIDatePicker.Mode.dateAndTime : UIDatePicker.Mode.date
// Creating a toolbar for the Picker
let toolbar = UIToolbar()
toolbar.sizeToFit()
// Creating buttons for toolbar
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(doneAction)) // ---- ERROR -----
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(cancelAction)) // ---- ERROR -----
// Adding buttons to the toolbar
toolbar.setItems([cancelButton,spaceButton,doneButton], animated: false)
// Adding the Toolbar to the dateTimePicker and returning the dateTimePicker
}
现在,当我尝试将闭包添加为按钮操作时,会出现问题,因为它们不是选择器(附加了@objc
)
我得到的错误是
“#selector”的参数不能引用参数“ doneAction”
如何解决此问题,或有另一种方法将要执行的代码(在“取消并完成”时)从main(ViewController)类传递到此实用工具类
答案 0 :(得分:2)
如果我对您的理解正确,则可以通过将委托添加到班级来解决此问题。这是一些如何做的例子。希望对您有帮助
protocol DoneCancelAction {
func doneAction()
func cancelAction()
}
class DateTimePicker: UIDatePicker {
var dateTimePicker: DateTimePicker!
var delegate: DoneCancelAction? = nil
func createDatePicker(isDateTime: Bool) -> UIDatePicker {
// Code for setting up the dateTime picker
// Deciding the picker mode for the picker
dateTimePicker.datePickerMode = isDateTime ? UIDatePicker.Mode.dateAndTime : UIDatePicker.Mode.date
// Creating a toolbar for the Picker
let toolbar = UIToolbar()
toolbar.sizeToFit()
// Creating buttons for toolbar
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: self, action: #selector(doneAction)) // ---- ERROR -----
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItem.Style.plain, target: self, action: #selector(cancelAction)) // ---- ERROR -----
// Adding buttons to the toolbar
toolbar.setItems([cancelButton,spaceButton,doneButton], animated: false)
// Adding the Toolbar to the dateTimePicker and returning the dateTimePicker
return dateTimePicker
}
@objc func doneAction() {
delegate?.doneAction()
}
@objc func cancelAction() {
delegate?.cancelAction()
}
}
class MyVC: UIViewController, DoneCancelAction {
var dateTimePicker: DateTimePicker!
override func viewDidLoad() {
super.viewDidLoad()
dateTimePicker.delegate = self
}
func doneAction() {
// your code
}
func cancelAction() {
// your code
}
}
答案 1 :(得分:1)
1。正确的方法是使用协议,只需使DateTypeProtocol向其添加提交按钮和取消按钮操作功能即可。
2。在实用工具类上创建单独的函数,并使用委托调用协议函数
3。然后在使用它时让使用它的类遵守协议并在那里执行操作。
答案 2 :(得分:1)
class Closure {
let closure: ()->()
init (_ closure: @escaping ()->()) {
self.closure = closure
}
@objc func action () {
closure()
}
}
extension UIBarButtonItem {
public convenience init(title: String?, style: UIBarButtonItem.Style, action: @escaping ()->()) {
let handle = Closure(action)
self.init(title: title, style: style, target: handle, action: #selector(Closure.action))
objc_setAssociatedObject(self, "ex_action", handle, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, action: doneAction)