Jak można ustawić akcję dla niestandardowego elementu UIBarButtonItem w języku Swift?
Poniższy kod pomyślnie umieszcza przycisk na pasku nawigacyjnym:
var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:nil)
self.navigationItem.rightBarButtonItem = b
Teraz chciałbym zadzwonić func sayHello() { println("Hello") }
po dotknięciu przycisku. Moje dotychczasowe wysiłki:
var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:sayHello:)
// also with `sayHello` `sayHello()`, and `sayHello():`
i..
var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:@selector(sayHello:))
// also with `sayHello` `sayHello()`, and `sayHello():`
i..
var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:@selector(self.sayHello:))
// also with `self.sayHello` `self.sayHello()`, and `self.sayHello():`
Zauważ, że sayHello()
pojawia się w trybie Intellisense, ale nie działa.
Dzięki za pomoc.
EDYCJA: Dla potomnych następujące prace:
var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:"sayHello")
ios
swift
action
uibarbuttonitem
kmiklas
źródło
źródło
action: "sayHello"
UIBarButtonItem
podczas gdy drugie nie. Wymaganie od początkujących uogólniania wszystkich zastosowańselector
może być dla nich trudne, więc usuwam status zduplikowany, aby ludzie mogli aktualizować to pytanie.Odpowiedzi:
Od wersji Swift 2.2 istnieje specjalna składnia dla selektorów sprawdzanych w czasie kompilacji. Używa składni:
#selector(methodName)
.Swift 3 i nowsze:
var b = UIBarButtonItem( title: "Continue", style: .plain, target: self, action: #selector(sayHello(sender:)) ) func sayHello(sender: UIBarButtonItem) { }
Jeśli nie jesteś pewien, jak powinna wyglądać nazwa metody, istnieje specjalna wersja polecenia kopiowania, która jest bardzo pomocna. Umieść kursor gdzieś w nazwie metody bazowej (np. SayHello) i naciśnij Shift+ Control+ Option+ C. To powoduje umieszczenie „nazwy symbolu” na klawiaturze do wklejenia. Jeśli również Commandgo posiadasz , skopiuje „kwalifikowaną nazwę symbolu”, która będzie zawierała również typ.
Swift 2.3:
var b = UIBarButtonItem( title: "Continue", style: .Plain, target: self, action: #selector(sayHello(_:)) ) func sayHello(sender: UIBarButtonItem) { }
Dzieje się tak, ponieważ pierwsza nazwa parametru nie jest wymagana w Swift 2.3 podczas wywoływania metody.
Możesz dowiedzieć się więcej o składni na swift.org tutaj: https://swift.org/blog/swift-2-2-new-features/#compile-time-checked-selectors
źródło
Selector("sayHello")
za kulisami przez Swift.Przykład Swift 4/5
button.target = self button.action = #selector(buttonClicked(sender:)) @objc func buttonClicked(sender: UIBarButtonItem) { }
źródło
@objc
do deklaracji funkcji. Aż do wersji Swift 4 wywnioskowano to niejawnie.button.target = self
Przykład automatyzacji Swift 5 i iOS 13+
@objc
, patrz poniższy przykład!#selector(name)
.private
lubpublic
nie ma znaczenia; możesz użyć prywatnego.Przykład kodu
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let menuButtonImage = UIImage(systemName: "flame") let menuButton = UIBarButtonItem(image: menuButtonImage, style: .plain, target: self, action: #selector(didTapMenuButton)) navigationItem.rightBarButtonItem = menuButton } @objc public func didTapMenuButton() { print("Hello World") }
źródło
Niech ten pomoże trochę więcej
Załóżmy, że jeśli chcesz utworzyć przycisk paska w oddzielnym pliku (dla podejścia modułowego) i chcesz zwrócić selektor z powrotem do kontrolera widoku, możesz zrobić to w następujący sposób: -
plik narzędziowy
class GeneralUtility { class func customeNavigationBar(viewController: UIViewController,title:String){ let add = UIBarButtonItem(title: "Play", style: .plain, target: viewController, action: #selector(SuperViewController.buttonClicked(sender:))); viewController.navigationController?.navigationBar.topItem?.rightBarButtonItems = [add]; } }
Następnie utwórz klasę SuperviewController i zdefiniuj w niej tę samą funkcję.
class SuperViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } @objc func buttonClicked(sender: UIBarButtonItem) { } }
iw naszym podstawowym viewController (który dziedziczy twoją klasę SuperviewController) przesłania tę samą funkcję
import UIKit class HomeViewController: SuperViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func viewWillAppear(_ animated: Bool) { GeneralUtility.customeNavigationBar(viewController: self,title:"Event"); } @objc override func buttonClicked(sender: UIBarButtonItem) { print("button clicked") } }
Teraz po prostu odziedzicz SuperViewController w dowolnej klasie, w której chcesz ten barbutton.
Dzięki za przeczytanie
źródło
Szybki 5
jeśli utworzyłeś
UIBarButtonItem
w Interface Builder i podłączyłeś outlet do elementu i chcesz programowo powiązać selektor.Nie zapomnij ustawić celu i selektora.
addAppointmentButton.action = #selector(moveToAddAppointment) addAppointmentButton.target = self @objc private func moveToAddAppointment() { self.presenter.goToCreateNewAppointment() }
źródło