Swift 3.0如何在导航栏中添加右侧按钮

31

我在视图控制器的顶部添加了一个导航栏。我正在尝试根据条件控制是否显示一个按钮,但我无法添加这个按钮。到目前为止,我已经:

var addButton: UIBarButtonItem = UIBarButtonItem(title: "test", style: .done, target: self, action: #selector(addTapped))

override func viewDidLoad() {
    super.viewDidLoad()

    let boool = true
    if boool {
        self.navigationItem.rightBarButtonItem = self.addButton
    }
    else {
        self.navigationItem.rightBarButtonItem = nil
    }
}

func addTapped(sender: AnyObject) {
    print("hjxdbsdhjbv")
}

我认为它无法正常工作,是因为我在VC中添加了一个导航栏,而没有使用导航控制器并与那里的栏一起工作。 我想知道是否有一种方法可以使用此导航栏。


你确定self.addButton指向一个实际的UIBarButtonItem而不是nil吗?它是如何设置的? - Seamus Campbell
我认为你必须在使用self.addButton之前进行初始化。 - Reinier Melian
将此行代码 var addButton: UIBarButtonItem! 更改为 var addButton: UIBarButtonItem = UIBarButtonItem(title: "test", style: .done, target: self, action: #selector(self.yourselector)) - Reinier Melian
我已经编辑了我的问题以反映更改,但在加载时,右侧仍然没有按钮。 - Kevin
6个回答

68
很简单。将这行代码放到 viewDidLoad 中即可:
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "test", style: .done, target: self, action: #selector(addTapped))

已更新至Swift 4或更高版本:

一个自定义函数:

@objc func action(sender: UIBarButtonItem) {
    // Function body goes here
}

(自定义) 右侧栏按钮项:

self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(title: "some_text", style: .done, target: self, action: #selector(self.action(sender:)))

(自定义)左侧栏按钮:

self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(title: "some_text", style: .done, target: self, action: #selector(self.action(sender:)))

您还可以像这样添加系统栏按钮项目:UIBarButtonItem.SystemItem 定义了用于栏按钮项的系统提供的图像:.add、.done、.cancel、.edit、.save、.compose、.reply、.organize 等等。

(系统) 右侧栏按钮项:

self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(self.action(sender:)))

(系统) 左侧按钮项:

self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonItem.SystemItem.add, target: self, action: #selector(self.action(sender:)))

2
适用于Swift 4。 - Ahmadreza
1
非常感谢,但为什么? - Dean Lee

9
let rightBarButtonItem = UIBarButtonItem.init(image: UIImage(named: "EditImage"), style: .done, target: self, action: #selector(ViewController.call_Method))

self.navigationItem.rightBarButtonItem = rightBarButtonItem

1
@Devbot10 如果你认为问题有任何缺陷,出于任何原因,你必须留下评论,而不是尝试编辑别人的答案。 - user4396006

7
你说你通过storyboard向视图控制器添加了一个UINavigationBar,但是根据你提供的代码,IB中没有与导航栏相连的outlet。为了访问self.navigationItem,你的视图控制器必须嵌入在UINavigationController中或者成为这个层次结构的一部分。除非你需要在单个视图控制器上使用自定义导航栏,否则建议从Interface Builder中删除它,然后确保要么将相关的视图控制器嵌入到UINavigationController中,要么将其从另一个嵌入在导航控制器中的控制器推入到导航堆栈中,然后你就能看到你的UIBarButtonItem了。

1
使用嵌入式UINavigationController相比自定义导航栏有哪些好处? - Kevin
2
将您的视图控制器嵌入导航控制器中,可以在界面构建器中拥有清晰的导航堆栈,并且对于该导航堆栈中的每个视图控制器,您都可以访问相同的导航栏。相反,如果您将一个导航栏添加到一个视图控制器中,那么您将不得不在下一个视图控制器中再次添加另一个导航栏,同时分别管理每个导航栏。 - Kyle H

2
首先,您需要将导航栏连接到 IBOutlet,以便在代码中引用它。之后,这段代码应该可以正常工作:
    let navigationItem = UINavigationItem(title: "Title")
    navigationItem.rightBarButtonItem = self.addButton
    navigationItem.hidesBackButton = true
    self.navigationBar.pushItem(navigationItem, animated: false)

我在这个导航控制器上添加了一个返回按钮。除了你的代码之外,我还添加了@IBOutlet weak var navigationBar: UINavigationBar!。但是当点击返回按钮时,它只会移除导航栏并显示下面的内容。有点难以解释,但你知道我在说什么吗? - Kevin
2
返回的视图控制器需要有自己的 UINavigationBar。这就是为什么最好使用 UINavigationController 的原因。 - Stefan S

2
Swift 4.2; 添加viewController
override func viewDidLoad() {
        super.viewDidLoad()
        self.addNavigationBarButton(imageName: "ic_back", direction:.left)
 }

Class添加到您的API或实用类中。最初的回答。
public func addNavigationBarButton(imageName:String,direction:direction){
    var image = UIImage(named: imageName)
    image = image?.withRenderingMode(.alwaysOriginal)
    switch direction {
    case .left:
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
    case .right:
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style:.plain, target: nil, action: #selector(goBack))
    }
}

@objc public func goBack() {
    self.navigationController?.popViewController(animated: true)
}

public enum direction {
    case right
    case left
}

1

本文介绍在Xcode 10.2和Swift 5.0中进行的测试; 首先,我已经在IB中将我的ViewController嵌入到了UINavigationController中。 然后在ViewDidLoad中加入以下代码:

self.title = "orange"
 self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(changeLayout)).

注意 - 通过导航控制器访问标题或添加按钮并不起作用。例如:设置标题 - Self.navigationcontroller.navigationItem.title没有起作用,

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接