Ios 将选择器作为按钮目标操作传递给方法
这是我的设想。我要举杯庆祝。toast视图接受一个选择器,它将该选择器设置为toast视图中按钮的目标操作。但我得到了无法识别的选择器错误Ios 将选择器作为按钮目标操作传递给方法,ios,swift,unrecognized-selector,Ios,Swift,Unrecognized Selector,这是我的设想。我要举杯庆祝。toast视图接受一个选择器,它将该选择器设置为toast视图中按钮的目标操作。但我得到了无法识别的选择器错误 // MainViewController.swift func viewDidLoad() { // Custom initializer for toastview let toastView = ToastView(view: nil, selector: #selector(testSelector)) .
// MainViewController.swift
func viewDidLoad() {
// Custom initializer for toastview
let toastView = ToastView(view: nil, selector: #selector(testSelector))
.
.
.
}
@objc func testSelector() {
print("Test")
}
// ToastView.swift
var selector: Selector
convenience init(view: UIView, selector: Selector) {
self.selector = selector
let button = UIButton(type: .system)
button.addTarget(self, action: self.selector, for: .touchUpInside)
}
编辑:稍微更改代码以反映我的原始代码中的实际内容。您的目标错误。目标必须是定义选择器(方法或函数)的类的对象。如果在
MainViewController
中定义了函数,则目标必须是MainViewController
的对象。如果在ToastView
中定义了相同的函数,则选择器必须是ToastView
的对象
或者将类中的testSelector
函数移动到stview
类中,并保持其余部分不变
选项1
// something like this
class ToastView {
@objc func testSelector() {
print("Test")
}
}
选项2
或者将目标作为init
paramater传递
// ToastView.swift
convenience init(view: UIView, target:Any, selector: Selector) {
let button = UIButton(type: .system)
button.addTarget(target, action: selector, for: .touchUpInside)
}
在您的MainViewController
中,这样调用它
func viewDidLoad() {
// Custom initializer for toastview
let toastView = ToastView(view: nil, target:self, selector: #selector(testSelector))
.
.
.
}
你找错目标了。目标必须是定义选择器(方法或函数)的类的对象。如果在
MainViewController
中定义了函数,则目标必须是MainViewController
的对象。如果在ToastView
中定义了相同的函数,则选择器必须是ToastView
的对象
或者将类中的testSelector
函数移动到stview
类中,并保持其余部分不变
选项1
// something like this
class ToastView {
@objc func testSelector() {
print("Test")
}
}
选项2
或者将目标作为init
paramater传递
// ToastView.swift
convenience init(view: UIView, target:Any, selector: Selector) {
let button = UIButton(type: .system)
button.addTarget(target, action: selector, for: .touchUpInside)
}
在您的MainViewController
中,这样调用它
func viewDidLoad() {
// Custom initializer for toastview
let toastView = ToastView(view: nil, target:self, selector: #selector(testSelector))
.
.
.
}
不要传递选择器,相反,根本不需要传递任何选择器。
按下按钮时触发通知,并向控制器的通知中添加观察者。在与观测者连接的选择器中执行您想要的任何操作,不要传入选择器,而是根本不需要传入任何选择器。
按下按钮时触发通知,并向控制器的通知中添加观察者。在与观察者连接的选择器中执行所需的任何操作如果要在
ToastView
类中执行操作,则应将testSelector
移动到ToastView
类中
如果要在MainViewController
中执行操作,请使用自定义委托
或者在ToastView
类中全局声明按钮
变量。然后,您可以使用在MainViewController
中添加目标
let toastView = ToastView()
toastView.button.addTarget(target, action: selector, for: .touchUpInside)
或 您可以对按钮操作使用闭包,而不是选择器
class ToastView: UIView {
let button = UIButton()
var btnAction:((Void) -> Void)?
convenience init(_ btnAction: @escaping (Void) -> Void) {
self.init()
self.btnAction = btnAction
}
private init() {
super.init(frame: .zero)
button.addTarget(self, action: #selector(callbackButton(_:)), for: .touchUpInside)
}
func callbackButton(_ id:Any) -> Void {
if self.btnAction != nil {
self.btnAction!()
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
在MainViewController.swift中
func viewDidLoad() {
// Custom initializer for toastview
let toastView = ToastView.init( {(Void) -> Void in
print("test")
})
}
如果要在
ToastView
类中执行操作,应将testSelector
移动到ToastView
类
如果要在MainViewController
中执行操作,请使用自定义委托
或者在ToastView
类中全局声明按钮
变量。然后,您可以使用在MainViewController
中添加目标
let toastView = ToastView()
toastView.button.addTarget(target, action: selector, for: .touchUpInside)
或 您可以对按钮操作使用闭包,而不是选择器
class ToastView: UIView {
let button = UIButton()
var btnAction:((Void) -> Void)?
convenience init(_ btnAction: @escaping (Void) -> Void) {
self.init()
self.btnAction = btnAction
}
private init() {
super.init(frame: .zero)
button.addTarget(self, action: #selector(callbackButton(_:)), for: .touchUpInside)
}
func callbackButton(_ id:Any) -> Void {
if self.btnAction != nil {
self.btnAction!()
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
在MainViewController.swift中
func viewDidLoad() {
// Custom initializer for toastview
let toastView = ToastView.init( {(Void) -> Void in
print("test")
})
}
谢谢你的选择。但是添加一个观察者会给这样一个微小的特性增加开销。难道没有办法通过选择器让它工作吗?为什么?传递选择器将推断在toast的初始化过程中传递不同的方法,这意味着不同的控制器使用不同的方法。这里基本上是一样的。或者你也可以使用委托,但将选择器从控制器传递到视图基本上会带来麻烦。使用按钮按下通知几乎从来都不是解决方案。正如我所说的,这是一种观点,你也可以使用委托,但在我看来,使用按钮动作通知是比传递选择器更好的解决方案,另外,如果您决定传递选择器,请检查toast视图的deinit是否被调用,因为它可能会保留一些值,并且retain count可能永远不会达到0。但是添加一个观察者会给这样一个微小的特性增加开销。难道没有办法通过选择器让它工作吗?为什么?传递选择器将推断在toast的初始化过程中传递不同的方法,这意味着不同的控制器使用不同的方法。这里基本上是一样的。或者你也可以使用委托,但将选择器从控制器传递到视图基本上会带来麻烦。使用按钮按下通知几乎从来都不是解决方案。正如我所说的,这是一种观点,你也可以使用委托,但在我看来,使用按钮动作通知是比传递选择器更好的解决方案,另外,如果您决定传递选择器,请检查toast视图的deinit是否被调用,因为它可能会保留一些值,并且retain count可能永远不会达到0。button.addTarget(toast,selector:toast.selector,for:.touchUpInside)仍然存在相同的问题。您如何称呼它?将目标作为自身传递?否。将其更改为保留选择器的位置。(ToastView的例子)真的很抱歉。为了更好地反映我的实际用例,对问题做了一些修改。目标必须是定义选择器的地方。它是在viewcontriller中定义的,所以目标应该是self。将目标和选择器都传递给init是更好的解决方案。尝试了这个方法。button.addTarget(toast,selector:toast.selector,for:.touchUpInside)仍然存在相同的问题。您如何称呼它?将目标作为自身传递?否。将其更改为保留选择器的位置。(ToastView的例子)真的很抱歉。为了更好地反映我的实际用例,对问题做了一些修改。目标必须是定义选择器的地方。它在ViewController中定义,所以目标应该是self。传递两个ta