UIBarButtonItem en la barra de navegación mediante programación?

135

He estado buscando esta solución durante un tiempo, pero no tengo ninguna. por ejemplo, una solución es

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

Este código agregará un botón con la imagen "detener". Al igual que esto, hay otras soluciones con "buscar", "actualizar", etc. ¿ Pero qué pasa si quiero agregar un botón mediante programación con la imagen que quiero?

Rahul Sonvane
fuente

Respuestas:

342

Imagen de botón personalizada sin configurar el marco del botón:

Puede usar init(image: UIImage?, style: UIBarButtonItemStyle, target: Any?, action: Selector?)para inicializar un nuevo elemento utilizando la imagen especificada y otras propiedades.

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

Mira este documento de Apple. referencia


UIBarButtonItem con imagen de botón personalizada con marco de botón

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

PARA Swift 2.0y mayores

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

O simplemente use init (customView :) como

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

Para el sistema UIBarButtonItem

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

Para configurar más de 1 artículo, use rightBarButtonItemso para el lado izquierdoleftBarButtonItems

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]

Usando setLeftBarButtonItemosetRightBarButtonItem

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

Para swift> = 2.2 la acción debe ser #selector(Class.MethodName)... por ej.btnName.addTarget(self, action: #selector(Class.MethodName), forControlEvents: .TouchUpInside)

EI Capitán v2.0
fuente
Gran respuesta. Solo quiero señalar que el método Selector se ha actualizado alet camera = UIBarButtonItem(barButtonSystemItem: .Camera, target: self, action: #selector(Class.MethodName))
CodeBender
Descubrí que si desea que su botón también incluya el texto, debe especificar la parte CGRect. Hay algunos ejemplos flotando alrededor de SO que no especifican esto.
Micah Montoya
Gracias por tu respuesta perfecta. No está mal agregar una actualización para Swift 4.
Milad Faridnia
38

Es mucho más fácil con Swift 4oSwift 4.2

dentro de su ViewDidLoadmétodo, defina su botón y agréguelo a la barra de navegación.

override func viewDidLoad() {
    super.viewDidLoad()

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

}

entonces necesita definir la función que mencionó dentro del parámetro de acción como se muestra a continuación

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

Debe agregar el @objcprefijo ya que todavía está haciendo uso del material heredado (Objetivo C).

Jay Mayu
fuente
17

Simplemente configure UIBarButtonItemcon customView

Por ejemplo:

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

o usar setFunction:

  self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: yourButton), animated: true);
León
fuente
1
Estoy votando su respuesta ya que su código también funciona, pero el código de Bhavin es una solución única, así que aceptaré su respuesta. Gracias por tu contribución amigo :)
Rahul Sonvane
11

Me topé con esta pregunta y aquí hay una actualización para Swift 3 y iOS 10:

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

Definitivamente es mucho más rápido que crear el UIButton con todas las propiedades y luego agregar el CustomView al UIBarButtonItem.

Y si desea cambiar el color de la imagen del azul predeterminado a, por ejemplo, blanco, siempre puede cambiar el color del tinte:

test.tintColor = UIColor.white()

PD: obviamente, debe cambiar el selector, etc. para su aplicación :)

tech4242
fuente
7

En Swift 3.0+, UIBarButtonItemconfigure programáticamente de la siguiente manera:

   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")
     }
Kushal Shrestha
fuente
3

Configuración de LeftBarButton con imagen original.

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

Tengo el mismo problema y he leído las respuestas en otro tema y luego resuelvo otra forma similar. No sé cuál es más efectivo. problema similar

//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
fuente
1

Esto es una locura de manzana. Cuando diga self.navigationItem.rightBarButtonItem.title, dirá nil mientras que en la GUI muestra Editar o Guardar. A Fresher le gusto. Tomará mucho tiempo depurar este comportamiento.

Existe el requisito de que el elemento muestre Editar en la primera carga y luego el usuario lo toque. Cambiará a Guardar título. Para archivar esto, hice lo siguiente.

// la vista se cargó dirá Editar título

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

// toque Editar elemento cambiará a Guardar título

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

// toca Guardar elemento mostrará Editar título

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

}
codificadores
fuente
1

iOS 11

Establecer un botón personalizado con restricción:

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)
Achyut Sagar
fuente
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)
}

}
Sai kumar Reddy
fuente