简体   繁体   English

以编程方式在导航栏中的 UIBarButtonItem?

[英]UIBarButtonItem in navigation bar programmatically?

I've been looking around for this solution for a while but haven't got any.我一直在寻找这个解决方案一段时间,但没有任何解决方案。 eg one solution is例如一种解决方案是

 self.navigationItem.setRightBarButtonItem(UIBarButtonItem(barButtonSystemItem: .Stop, target: self, action: nil), animated: true)

This code will add a button with "stop" image.此代码将添加一个带有“停止”图像的按钮。 Just like this, there are other solutions with "search, "refresh" etc. But what if I want to add a button programmatically with the image I want?就像这样,还有其他“搜索”、“刷新”等解决方案。但是如果我想以编程方式添加一个带有我想要的图像的按钮怎么办?

Custom button image without setting button frame:不设置按钮框架的自定义按钮图像:

You can use init(image: UIImage?, style: UIBarButtonItemStyle, target: Any?, action: Selector?) to initializes a new item using the specified image and other properties.您可以使用init(image: UIImage?, style: UIBarButtonItemStyle, target: Any?, action: Selector?)使用指定的图像和其他属性初始化新项目。

let button1 = UIBarButtonItem(image: UIImage(named: "imagename"), style: .plain, target: self, action: Selector("action")) // action:#selector(Class.MethodName) for swift 3
self.navigationItem.rightBarButtonItem  = button1

Check this Apple Doc.检查此Apple 文档。 reference 参考


UIBarButtonItem with custom button image using button frame带有自定义按钮图像的 UIBarButtonItem 使用按钮框架

FOR Swift 3.0适用于Swift 3.0

    let btn1 = UIButton(type: .custom)
    btn1.setImage(UIImage(named: "imagename"), for: .normal)
    btn1.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
    btn1.addTarget(self, action: #selector(Class.Methodname), for: .touchUpInside)
    let item1 = UIBarButtonItem(customView: btn1)

    let btn2 = UIButton(type: .custom)
    btn2.setImage(UIImage(named: "imagename"), for: .normal)
    btn2.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
    btn2.addTarget(self, action: #selector(Class.MethodName), for: .touchUpInside)
    let item2 = UIBarButtonItem(customView: btn2)  

    self.navigationItem.setRightBarButtonItems([item1,item2], animated: true)

FOR Swift 2.0 and older适用于Swift 2.0及更早版本

let btnName = UIButton()
btnName.setImage(UIImage(named: "imagename"), forState: .Normal)
btnName.frame = CGRectMake(0, 0, 30, 30)
btnName.addTarget(self, action: Selector("action"), forControlEvents: .TouchUpInside)

//.... Set Right/Left Bar Button item
let rightBarButton = UIBarButtonItem()
rightBarButton.customView = btnName
self.navigationItem.rightBarButtonItem = rightBarButton

Or simply use init(customView:) like或者简单地使用init(customView:) 之类的

 let rightBarButton = UIBarButtonItem(customView: btnName) self.navigationItem.rightBarButtonItem = rightBarButton

For System UIBarButtonItem对于系统 UIBarButtonItem

let camera = UIBarButtonItem(barButtonSystemItem: .Camera, target: self, action: Selector("btnOpenCamera"))
self.navigationItem.rightBarButtonItem = camera

For set more then 1 items use rightBarButtonItems or for left side leftBarButtonItems要设置超过 1 个项目,请使用rightBarButtonItems或左侧leftBarButtonItems

let btn1 = UIButton()
btn1.setImage(UIImage(named: "img1"), forState: .Normal)
btn1.frame = CGRectMake(0, 0, 30, 30)
btn1.addTarget(self, action: Selector("action1:"), forControlEvents: .TouchUpInside)
let item1 = UIBarButtonItem()
item1.customView = btn1

let btn2 = UIButton()
btn2.setImage(UIImage(named: "img2"), forState: .Normal)
btn2.frame = CGRectMake(0, 0, 30, 30)
btn2.addTarget(self, action: Selector("action2:"), forControlEvents: .TouchUpInside)
let item2 = UIBarButtonItem()
item2.customView = btn2

self.navigationItem.rightBarButtonItems = [item1,item2]

Using setLeftBarButtonItem or setRightBarButtonItem使用setLeftBarButtonItemsetRightBarButtonItem

let btn1 = UIButton()
btn1.setImage(UIImage(named: "img1"), forState: .Normal)
btn1.frame = CGRectMake(0, 0, 30, 30)
btn1.addTarget(self, action: Selector("action1:"), forControlEvents: .TouchUpInside)
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: btn1), animated: true);

For swift >= 2.2 action should be #selector(Class.MethodName) ... for eg btnName.addTarget(self, action: #selector(Class.MethodName), forControlEvents: .TouchUpInside)对于 swift >= 2.2 action 应该是#selector(Class.MethodName) ... 例如btnName.addTarget(self, action: #selector(Class.MethodName), forControlEvents: .TouchUpInside)

It's much easier with Swift 4 or Swift 4.2使用Swift 4Swift 4.2更容易

inside your ViewDidLoad method, define your button and add it to the navigation bar.在您的ViewDidLoad方法中,定义您的按钮并将其添加到导航栏。

override func viewDidLoad() {
    super.viewDidLoad()

    let logoutBarButtonItem = UIBarButtonItem(title: "Logout", style: .done, target: self, action: #selector(logoutUser))
    self.navigationItem.rightBarButtonItem  = logoutBarButtonItem

}

then you need to define the function that you mentioned inside action parameter as below那么你需要定义你在 action 参数中提到的函数,如下所示

@objc func logoutUser(){
     print("clicked")
}

You need to add the @objc prefix as it's still making use of the legacy stuff (Objective C).您需要添加@objc前缀,因为它仍在使用遗留的东西(目标 C)。

Just setup UIBarButtonItem with customView只需设置UIBarButtonItem与customView

For example:例如:

  var leftNavBarButton = UIBarButtonItem(customView:yourButton)
  self.navigationItem.leftBarButtonItem = leftNavBarButton

or use setFunction :或使用setFunction

  self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: yourButton), animated: true);

I just stumbled upon this question and here is an update for Swift 3 and iOS 10:我偶然发现了这个问题,这里是 Swift 3 和 iOS 10 的更新:

let testUIBarButtonItem = UIBarButtonItem(image: UIImage(named: "test.png"), style: .plain, target: self, action: nil)
self.navigationItem.rightBarButtonItem  = testUIBarButtonItem

It is definitely much faster than creating the UIButton with all the properties and then subsequently adding the customView to the UIBarButtonItem.它绝对比创建具有所有属性的 UIButton 然后将 customView 添加到 UIBarButtonItem 快得多。

And if you want to change the color of the image from the default blue to eg white, you can always change the tint color:如果您想将图像的颜色从默认的蓝色更改为例如白色,您可以随时更改色调颜色:

test.tintColor = UIColor.white()

PS You should obviously change the selector etc. for your app :) PS您显然应该为您的应用更改选择器等:)

In Swift 3.0+, UIBarButtonItem programmatically set up as follows:在 Swift 3.0+ 中, UIBarButtonItem编程方式设置如下:

   override func viewDidLoad() {
        super.viewDidLoad()
        let testUIBarButtonItem = UIBarButtonItem(image: UIImage(named: "test.png"), style: .plain, target: self, action: #selector(self.clickButton))
        self.navigationItem.rightBarButtonItem  = testUIBarButtonItem
    }

   @objc func clickButton(){
            print("button click")
     }

Setting LeftBarButton with Original Image.使用原始图像设置 LeftBarButton。

let menuButton = UIBarButtonItem(image: UIImage(named: "imagename").withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(classname.functionname))
self.navigationItem.leftBarButtonItem  = menuButton

I have same issue and I have read answers in another topic then I solve another similar way.我有同样的问题,我已经阅读了另一个主题的答案,然后我解决了另一种类似的方法。 I do not know which is more effective.我不知道哪个更有效。 similar issue 类似的问题

//play button

@IBAction func startIt(sender: AnyObject) {
    startThrough();
};

//play button

func startThrough() {
    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateTime"), userInfo: nil, repeats: true);

    let pauseButton = UIBarButtonItem(barButtonSystemItem: .Pause, target: self, action: "pauseIt");
    self.toolBarIt.items?.removeLast();
    self.toolBarIt.items?.append( pauseButton );
}

func pauseIt() {
    timer.invalidate();

    let play = UIBarButtonItem(barButtonSystemItem: .Play, target: self, action: "startThrough");
    self.toolBarIt.items?.removeLast();
    self.toolBarIt.items?.append( play );
}

iOS 11 iOS 11

Setting a custom button using constraint:使用约束设置自定义按钮:

let buttonWidth = CGFloat(30)
let buttonHeight = CGFloat(30)

let button = UIButton(type: .custom)
button.setImage(UIImage(named: "img name"), for: .normal)
button.addTarget(self, action: #selector(buttonTapped(sender:)), for: .touchUpInside)
button.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
button.heightAnchor.constraint(equalToConstant: buttonHeight).isActive = true

self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: button)

This is a crazy thing of apple.这是苹果的疯狂之举。 When you say self.navigationItem.rightBarButtonItem.title then it will say nil while on the GUI it shows Edit or Save.当你说 self.navigationItem.rightBarButtonItem.title 然后它会说 nil 而在 GUI 上它显示编辑或保存。 Fresher likes me will take a lot of time to debug this behavior. Fresher like me 会花很多时间来调试这种行为。

There is a requirement that the Item will show Edit in the firt load then user taps on it It will change to Save title.有一个要求,项目将在第一次加载中显示编辑,然后用户点击它会更改为保存标题。 To archive this, i did as below.为了归档这个,我做了如下。

//view did load will say Edit title //view did load 会说编辑标题

private func loadRightBarItem() {
    let logoutBarButtonItem = UIBarButtonItem(title: "Edit", style: .done, target: self, action: #selector(handleEditBtn))
    self.navigationItem.rightBarButtonItem  = logoutBarButtonItem
}

// tap Edit item will change to Save title // 点击编辑项目将更改为保存标题

@objc private func handleEditBtn() {
    print("clicked on Edit btn")
    let logoutBarButtonItem = UIBarButtonItem(title: "Save", style: .done, target: self, action: #selector(handleSaveBtn))
    self.navigationItem.rightBarButtonItem  = logoutBarButtonItem
    blockEditTable(isBlock: false)
}

//tap Save item will display Edit title //点击保存项目将显示编辑标题

@objc private func handleSaveBtn(){
    print("clicked on Save btn")
    let logoutBarButtonItem = UIBarButtonItem(title: "Edit", style: .done, target: self, action: #selector(handleEditBtn))
    self.navigationItem.rightBarButtonItem  = logoutBarButtonItem

    saveInvitation()
    blockEditTable(isBlock: true)

}

FOR Swift 5+适用于 Swift 5+

let searchBarButtonItem = UIBarButtonItem(image: UIImage(named: "searchIcon"), style: .plain, target: self, action: #selector(onSearchButtonClicked))
        self.navigationItem.rightBarButtonItem  = searchBarButtonItem

@objc func onSearchButtonClicked(_ sender: Any){
    print("SearchButtonClicked")
}
func viewDidLoad(){
let homeBtn: UIButton = UIButton(type: UIButtonType.custom)

        homeBtn.setImage(UIImage(named: "Home.png"), for: [])

        homeBtn.addTarget(self, action: #selector(homeAction), for: UIControlEvents.touchUpInside)

        homeBtn.frame = CGRect(x: 0, y: 0, width: 30, height: 30)

        let homeButton = UIBarButtonItem(customView: homeBtn)


        let backBtn: UIButton = UIButton(type: UIButtonType.custom)

        backBtn.setImage(UIImage(named: "back.png"), for: [])

        backBtn.addTarget(self, action: #selector(backAction), for: UIControlEvents.touchUpInside)

        backBtn.frame = CGRect(x: -10, y: 0, width: 30, height: 30)

        let backButton = UIBarButtonItem(customView: backBtn)
        self.navigationItem.setLeftBarButtonItems([backButton,homeButton], animated: true)
}

}

addition to the above you may use the following for ios14 and above除了以上内容,您还可以在 ios14 及以上版本中使用以下内容

   if #available(iOS 14.0, *) {
        let closeAction = UIAction(handler: { [weak self] _ in
           //perform action here
        })
        let closeBarButtonItem = UIBarButtonItem(systemItem: .close, primaryAction: closeAction, menu: nil)
        navigationItem.rightBarButtonItem  = closeBarButtonItem
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM