我的NavAction有问题,项目按钮在触摸后没有调用定义的操作。我在viewDidload函数之外定义了UIBarButtonItem:
let uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: self, action: #selector(uploadHandler))
然后我将其添加到NavBar中(在viewDidLoad((中(:
self.navigationItem.setRightBarButton(uploadButton, animated: true)
self.navigationItem.rightBarButtonItem!.setTitleTextAttributes([.font : UIFont.systemFont(ofSize: 14, weight: .heavy), .foregroundColor : UIColor.label], for: .normal)
如果我点击按钮,什么都没有发生,就不会调用操作,但如果我点击textView或textField并开始键入,之后如果我点击该按钮,就会调用操作。我曾试图让FirstResponder辞职,认为这是问题所在,但无济于事。有什么想法吗?提前Thanx。
问题是uploadButton
初始化太早,即在视图控制器ifself初始化期间。此时,self
还没有准备好使用。
有几种方法可以解决这个问题。
- 初始化
viewDidLoad
中的按钮:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: self, action: #selector(uploadHandler))
self.navigationItem.setRightBarButton(uploadButton, animated: false)
}
...
}
- 如果类中的某些其他方法需要访问它,请通过创建一个隐式展开的存储属性并在
viewDidLoad
中设置它来稍微修改上面的代码:
class MyViewController: UIViewController {
private var uploadButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: self, action: #selector(uploadHandler))
self.navigationItem.setRightBarButton(uploadButton, animated: false)
}
...
}
- 将按钮的初始化设为惰性,这样在第一次访问时就会对其进行初始化,即在viewDidLoad中:
class MyViewController: UIViewController {
private lazy var uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: self, action: #selector(uploadHandler))
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.setRightBarButton(uploadButton, animated: false)
}
...
}
- 初始化不带操作和选择器的按钮,稍后将它们添加到
viewDidLoad
中:
class MyViewController: UIViewController {
private let uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: nil, action: nil)
override func viewDidLoad() {
super.viewDidLoad()
uploadButton.target = self
uploadButton.action = #selector(uploadHandler)
self.navigationItem.setRightBarButton(uploadButton, animated: false)
}
...
}
所有这些选项之间几乎没有区别,所以无论你选择哪一个都应该没问题。
几个旁注:
- 在我的示例中,我将
uploadButton
声明为私有,以表明它不是视图控制器的公共API的一部分。如果您需要在视图控制器之外访问此按钮,只需移除private
修改器即可 viewDidLoad
中没有执行动画,因为您的视图还没有在屏幕上,所以调用setRightBarButton(uploadButton, animated: true)
不会触发动画,因此我用false
替换了true
。如果希望用户看到动画,请在viewDidAppear
中调用它