我有一个UIDatePicker
。选择日期后,我调用此方法
func goToNextScreen(selectedDate: Date) {
//...
}
现在,我添加了一个UIButton
。在该按钮操作中,我想调用相同的方法goToNextScreen
,而没有任何日期值。日期值在下一个屏幕中是可选的。我尝试了以下代码
btn.addTarget(self, action: #selector(goToNextScreen), for: .touchUpInside)//goToNextScreen(_:)
@objc func goToNextScreen(selectedDate: Date? = nil) {
//...
}
点击按钮时,应用崩溃。
如何在不添加其他方法的情况下解决此问题?如果不可能,为什么我的方法不起作用
答案 0 :(得分:3)
这里发生的是,按钮的内部逻辑试图将发送者(即UIButton
)传递到方法的Date
参数中。但是,如果您的方法没有任何参数,则将不会传递sender参数。
在这种情况下,可选参数实际上并不起作用。但是,您可以做的是为goToNextScreen
创建另一个无参数重载:
@objc func goToNextScreen() {
goToNextScreen(selectedDate: nil)
}
然后改变
btn.addTarget(self, action: #selector(goToNextScreen), for: .touchUpInside)
到
btn.addTarget(self, action: #selector(goToNextScreen as () -> Void), for: .touchUpInside)
以便两个重载之间有所不同。
请注意,仅编写#selector(goToNextScreen)
的原因是模棱两可的,因为您有两个名为goToNextScreen
的方法,而Swift需要解决其中一种方法。但这不能仅用名称。这是类似的情况:
class Foo {
@objc func f() {}
func f(x: Int) {}
let selector: Selector = #selector(f) // ambiguous use of f
}
编辑:如果不创建其他方法,则无法真正做到这一点。选择器是不灵活的东西。
答案 1 :(得分:2)
在这种情况下,不可能重复使用相同的方法。您应该创建一个不带参数或参数为UIButton
(或更通用的类型,通常为Any
)和UIEvent
的参数。
这是对目标动作机制的解释:UIControl。
答案 2 :(得分:1)
我认为您必须尝试一下
var selectedDate = Date()
btn.addTarget(self, action: #selector(goToNextScreen), for: .touchUpInside)//goToNextScreen(_:)
@objc func goToNextScreen(_ sender: UIButton)
{
selectedDate ?? self.datePickerDate : Date()
}
答案 3 :(得分:0)
使用Any
作为sender
类型并将其强制转换为Date
是可行的
//add button Target
btn.addTarget(self, action: #selector(goToNextScreen(_:)), for: .touchUpInside)
//Call with date value
goToNextScreen(Date())
@objc func goToNextScreen(_ selectedDate: Any) {
nextVC.date = selectedDate as? Date
//...
}
答案 4 :(得分:-1)
sender
的参数UIButton
被强制转换为Date
,这是崩溃的原因,它应该是UIButton
btn.addTarget(self, action: #selector(btnClicked), for: .touchUpInside)//goToNextScreen(_:)
@objc func btnClicked(_ sender:UIButton) {
// call next here
goToNextScreen()
}
func goToNextScreen(_ selectedDate: Date? = nil) {
if let date = selectedDate { }
}