将传递给方法的选择器分配为按钮目标操作
Assigning a selector passed to a method as a button target action
这是我的场景。我正在做吐司视图。 toast 视图接受一个选择器,它设置为 toast 视图内按钮的目标操作。但是我收到无法识别的选择器错误。
// 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)
}
编辑:稍微更改了代码以反映我原始代码中的实际内容。
你弄错了目标。目标必须是定义选择器(方法或函数)的 class 的对象。如果在 MainViewController
中定义了函数,则目标必须是 MainViewController
的对象。如果函数在 ToastView
中定义,选择器必须是 ToastView
的对象,则相同。
要么将 testSelector
函数移动到 ToastView
class 中,然后保持其余不变。
选项 1
// something like this
class ToastView {
@objc func testSelector() {
print("Test")
}
}
选项 2
或者您将目标作为 init
参数传递。
// 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
class 中的操作,您应该将 testSelector
移动到您的 ToastView
class。
如果您想在 MainViewController
中执行操作,请使用自定义委托。
或者在ToastView
class中全局声明button
变量。然后您可以使用
在 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 视图内按钮的目标操作。但是我收到无法识别的选择器错误。
// 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)
}
编辑:稍微更改了代码以反映我原始代码中的实际内容。
你弄错了目标。目标必须是定义选择器(方法或函数)的 class 的对象。如果在 MainViewController
中定义了函数,则目标必须是 MainViewController
的对象。如果函数在 ToastView
中定义,选择器必须是 ToastView
的对象,则相同。
要么将 testSelector
函数移动到 ToastView
class 中,然后保持其余不变。
选项 1
// something like this
class ToastView {
@objc func testSelector() {
print("Test")
}
}
选项 2
或者您将目标作为 init
参数传递。
// 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
class 中的操作,您应该将 testSelector
移动到您的 ToastView
class。
如果您想在 MainViewController
中执行操作,请使用自定义委托。
或者在ToastView
class中全局声明button
变量。然后您可以使用
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")
})
}