UIBarButtonItem na pasku nawigacyjnym programowo?

138

Szukałem tego rozwiązania od jakiegoś czasu, ale żadnego nie mam. np. jednym rozwiązaniem jest

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

Ten kod doda przycisk z obrazem „stop”. Tak po prostu, istnieją inne rozwiązania z „wyszukiwaniem,„ odświeżaniem ”itp. Ale co, jeśli chcę programowo dodać przycisk z wybranym obrazem?

Rahul Sonvane
źródło

Odpowiedzi:

351

Niestandardowy obraz przycisku bez ustawiania ramki przycisku:

Możesz użyć init(image: UIImage?, style: UIBarButtonItemStyle, target: Any?, action: Selector?)do zainicjowania nowego elementu przy użyciu określonego obrazu i innych właściwości.

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

Sprawdź ten dokument Apple. odniesienie


UIBarButtonItem z niestandardowym obrazem przycisku za pomocą ramki przycisku

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

DLA Swift 2.0i starszych

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

Lub po prostu użyj init (customView :) jak

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

W przypadku systemu UIBarButtonItem

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

W przypadku zestawu więcej niż 1 elementów użyj rightBarButtonItemslub na lewą stronę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]

Za pomocą setLeftBarButtonItemlubsetRightBarButtonItem

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

Dla swift> = 2.2 działanie powinno być #selector(Class.MethodName)... npbtnName.addTarget(self, action: #selector(Class.MethodName), forControlEvents: .TouchUpInside)

EI Captain v2.0
źródło
Świetna odpowiedź. Chcę tylko zaznaczyć, że metoda Selector została zaktualizowana dolet camera = UIBarButtonItem(barButtonSystemItem: .Camera, target: self, action: #selector(Class.MethodName))
CodeBender
Odkryłem, że jeśli chcesz, aby twój przycisk zawierał również tekst, musisz określić część CGRect. Istnieje kilka przykładów pływających po SO, które tego nie określają.
Micah Montoya,
dzięki za doskonałą odpowiedź. Nie jest źle dodać aktualizację dla Swift 4.
Milad Faridnia
40

Dużo łatwiej jest z Swift 4lubSwift 4.2

wewnątrz ViewDidLoadmetody zdefiniuj przycisk i dodaj go do paska nawigacji.

override func viewDidLoad() {
    super.viewDidLoad()

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

}

Następnie musisz zdefiniować funkcję, o której wspomniałeś w parametrze akcji, jak poniżej

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

Musisz dodać @objcprzedrostek, ponieważ nadal korzysta ze starszych rzeczy (cel C).

Jay Mayu
źródło
17

Po prostu skonfiguruj za UIBarButtonItempomocą customView

Na przykład:

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

lub użyj setFunction:

  self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: yourButton), animated: true);
Lew
źródło
1
Głosuję na twoją odpowiedź, ponieważ twój kod również działa, ale kod Bhavina jest rozwiązaniem jednorazowym, więc przyjmuję jego odpowiedź. Dzięki za twój wkład kolego :)
Rahul Sonvane
12

Właśnie natknąłem się na to pytanie i oto aktualizacja dla Swift 3 i iOS 10:

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

Jest to zdecydowanie znacznie szybsze niż tworzenie UIButton ze wszystkimi właściwościami, a następnie dodawanie customView do UIBarButtonItem.

A jeśli chcesz zmienić kolor obrazu z domyślnego niebieskiego na np. Biały, zawsze możesz zmienić kolor odcienia:

test.tintColor = UIColor.white()

PS Oczywiście powinieneś zmienić selektor itp. Dla swojej aplikacji :)

tech4242
źródło
7

W Swift 3.0+ UIBarButtonItemskonfiguruj programowo w następujący sposób:

   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
źródło
3

Ustawianie LeftBarButton z oryginalnym obrazem.

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

Mam ten sam problem i przeczytałem odpowiedzi w innym temacie to rozwiązuję inny podobny sposób. Nie wiem, który jest bardziej skuteczny. podobny problem

//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
źródło
1

To szalona sprawa jabłka. Kiedy powiesz self.navigationItem.rightBarButtonItem.title, to powie nil, podczas gdy w GUI wyświetli się Edytuj lub Zapisz. Fresher lubi mnie zajmie dużo czasu na debugowanie tego zachowania.

Istnieje wymóg, aby element wyświetlał Edytuj w pierwszym załadowaniu, a następnie użytkownik go stuka. Zmieni się na Zapisz tytuł. Aby to zarchiwizować, zrobiłem jak poniżej.

// Widok się załadował, powie Edytuj tytuł

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

// dotknij Edytuj element zmieni się na Zapisz tytuł

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

// stuknij Zapisz, wyświetli się tytuł edycji

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

}
programistów
źródło
1

iOS 11

Ustawianie przycisku niestandardowego za pomocą ograniczenia:

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
źródło
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
źródło