Программно UIBarButtonItem в панели навигации?

135

Некоторое время я искал это решение, но его нет. например, одно решение

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

Этот код добавит кнопку с изображением «стоп». Так же, есть и другие решения с «поиском», «обновлением» и т. Д. Но что, если я хочу программно добавить кнопку с нужным мне изображением?

Рахул Сонвейн
источник

Ответы:

343

Пользовательское изображение кнопки без настройки рамки кнопки:

Вы можете использовать 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

Проверьте этот Apple Doc. ссылка


UIBarButtonItem с пользовательским изображением кнопки с использованием рамки кнопки

ДЛЯ 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)

ДЛЯ 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

Или просто используйте init (customView :), например

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

Для системы UIBarButtonItem

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

Для набора более 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]

Используя setLeftBarButtonItemилиsetRightBarButtonItem

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);

Для быстрого> = 2.2 действие должно быть #selector(Class.MethodName)... например,btnName.addTarget(self, action: #selector(Class.MethodName), forControlEvents: .TouchUpInside)

EI Captain v2.0
источник
Отличный ответ. Просто хочу отметить, что метод Selector был обновлен доlet camera = UIBarButtonItem(barButtonSystemItem: .Camera, target: self, action: #selector(Class.MethodName))
CodeBender
Я обнаружил, что если вы хотите, чтобы ваша кнопка также включала текст, вы должны указать часть CGRect. Есть несколько примеров, плавающих вокруг SO, которые не указывают этого.
Мика Монтойя,
спасибо за прекрасный ответ. Неплохо добавить обновление для
Swift
38

С Swift 4илиSwift 4.2

внутри вашего ViewDidLoadметода определите свою кнопку и добавьте ее на панель навигации.

override func viewDidLoad() {
    super.viewDidLoad()

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

}

тогда вам нужно определить функцию, которую вы упомянули внутри параметра действия, как показано ниже

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

Вам нужно добавить @objcпрефикс, поскольку он все еще использует устаревший материал (цель C).

Джей Маю
источник
17

Просто установите UIBarButtonItemс помощью customView

Например:

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

или используйте setFunction:

  self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: yourButton), animated: true);
Лео
источник
1
Я голосую за ваш ответ, так как ваш код тоже работает, но код Бхавина - это одноразовое решение, поэтому я приму его ответ. Спасибо за ваш вклад, друг :)
Рахул Сонвейн
11

Я только что наткнулся на этот вопрос, и вот обновление для Swift 3 и iOS 10:

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

Это определенно намного быстрее, чем создание UIButton со всеми свойствами и последующее добавление customView в UIBarButtonItem.

И если вы хотите изменить цвет изображения с синего по умолчанию на белый, вы всегда можете изменить цвет оттенка:

test.tintColor = UIColor.white()

PS Вам, очевидно, следует изменить селектор и т. Д. Для своего приложения :)

tech4242
источник
7

В 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")
     }
Кушал Шреста
источник
3

Установка LeftBarButton с исходным изображением.

let menuButton = UIBarButtonItem(image: UIImage(named: "imagename").withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(classname.functionname))
self.navigationItem.leftBarButtonItem  = menuButton
Судхи 9135
источник
2

У меня такая же проблема, и я прочитал ответы в другой теме, а затем решаю другой аналогичный способ. Не знаю, что эффективнее. аналогичная проблема

//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 );
}
AngelThread
источник
1

Это безумная вещь из яблок. Когда вы говорите self.navigationItem.rightBarButtonItem.title, тогда он скажет nil, а в графическом интерфейсе отображается Edit или Save. Фрешер любит меня, и потребуется много времени, чтобы отладить такое поведение.

Требуется, чтобы элемент отображал Edit при первой загрузке, после чего пользователь нажимает на него. Он изменится на Сохранить заголовок. Чтобы заархивировать это, я сделал, как показано ниже.

// при просмотре загрузится сообщение Изменить заголовок

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

// коснитесь элемента Изменить, чтобы сохранить заголовок

@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)
}

// коснитесь элемента Сохранить, отобразится Изменить заголовок

@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)

}
кодеры
источник
1

iOS 11

Установка настраиваемой кнопки с использованием ограничения:

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)
Ачют Сагар
источник
0
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)
}

}
Саи Кумар Редди
источник