以编程方式添加到导航栏的 UIBarButtonItem 无法调用选择器,而添加到工具栏的按钮却可以
UIBarButtonItem added programatically to nav bar fails to call selector, while button added to toolbar does
我有一个有点困惑的问题。在我的应用程序中,我有一个工具栏,可以以编程方式换出按钮并正确调用关联的选择器。但是,当我将相同的技术应用于导航栏上的按钮时,它无法调用选择器。以下示例代码包含 2 组按钮(一组用于导航,一组用于工具栏)。尽管完全相同,但从未调用导航栏按钮上的选择器。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var toolbar: UIToolbar!
let navCancelButton = UIBarButtonItem(barButtonSystemItem: .cancel,
target: self,
action: #selector(toggleDelete))
let navTrashButton = UIBarButtonItem(barButtonSystemItem: .trash,
target: self,
action: #selector(toggleDelete))
let toolbarCancelButton = UIBarButtonItem(barButtonSystemItem: .cancel,
target: self,
action: #selector(toggleDelete))
let toolbarTrashButton = UIBarButtonItem(barButtonSystemItem: .trash,
target: self,
action: #selector(toggleDelete))
var isDeleting = false {
didSet {
navigationItem.rightBarButtonItem = isDeleting ? navCancelButton : navTrashButton
toolbar.items = isDeleting ? [toolbarCancelButton] : [toolbarTrashButton]
}
}
override func viewDidLoad() {
super.viewDidLoad()
isDeleting = false
}
@objc func toggleDelete() {
isDeleting = !isDeleting
}
}
这显示了之前的代码:
导航栏中的按钮似乎失去了目标。因此,您可以像这样在 viewDidLoad 中设置目标:
self.navTrashButton.target = self
self.navCancelButton.target = self
或者我要做的就是将变量放在 class 范围内,如下所示:
var navCancelButton: UIBarButtonItem!
var navTrashButton: UIBarButtonItem!
然后像这样在 viewDidLoad 中创建它们:
navCancelButton = UIBarButtonItem(barButtonSystemItem: .cancel,
target: self,
action: #selector(toggleDelete))
navTrashButton = UIBarButtonItem(barButtonSystemItem: .trash,
target: self,
action: #selector(toggleDelete))
这样你就知道按钮是在视图控制器期望它们准备就绪时创建的。
事实是目标正在丢失,它可能是 "bug",一个可能的解决方法是使用 lazy var
lazy var navCancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(toggleDelete))
lazy var navTrashButton = UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(toggleDelete))
我有一个有点困惑的问题。在我的应用程序中,我有一个工具栏,可以以编程方式换出按钮并正确调用关联的选择器。但是,当我将相同的技术应用于导航栏上的按钮时,它无法调用选择器。以下示例代码包含 2 组按钮(一组用于导航,一组用于工具栏)。尽管完全相同,但从未调用导航栏按钮上的选择器。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var toolbar: UIToolbar!
let navCancelButton = UIBarButtonItem(barButtonSystemItem: .cancel,
target: self,
action: #selector(toggleDelete))
let navTrashButton = UIBarButtonItem(barButtonSystemItem: .trash,
target: self,
action: #selector(toggleDelete))
let toolbarCancelButton = UIBarButtonItem(barButtonSystemItem: .cancel,
target: self,
action: #selector(toggleDelete))
let toolbarTrashButton = UIBarButtonItem(barButtonSystemItem: .trash,
target: self,
action: #selector(toggleDelete))
var isDeleting = false {
didSet {
navigationItem.rightBarButtonItem = isDeleting ? navCancelButton : navTrashButton
toolbar.items = isDeleting ? [toolbarCancelButton] : [toolbarTrashButton]
}
}
override func viewDidLoad() {
super.viewDidLoad()
isDeleting = false
}
@objc func toggleDelete() {
isDeleting = !isDeleting
}
}
这显示了之前的代码:
导航栏中的按钮似乎失去了目标。因此,您可以像这样在 viewDidLoad 中设置目标:
self.navTrashButton.target = self
self.navCancelButton.target = self
或者我要做的就是将变量放在 class 范围内,如下所示:
var navCancelButton: UIBarButtonItem!
var navTrashButton: UIBarButtonItem!
然后像这样在 viewDidLoad 中创建它们:
navCancelButton = UIBarButtonItem(barButtonSystemItem: .cancel,
target: self,
action: #selector(toggleDelete))
navTrashButton = UIBarButtonItem(barButtonSystemItem: .trash,
target: self,
action: #selector(toggleDelete))
这样你就知道按钮是在视图控制器期望它们准备就绪时创建的。
事实是目标正在丢失,它可能是 "bug",一个可能的解决方法是使用 lazy var
lazy var navCancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(toggleDelete))
lazy var navTrashButton = UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(toggleDelete))