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?

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)


Ś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).


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

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


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

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

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

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)

}

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)

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

}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.