Cara menyetel tindakan untuk UIBarButtonItem di Swift

89

Bagaimana tindakan untuk UIBarButtonItem kustom di Swift disetel?

Kode berikut berhasil menempatkan tombol di bilah navigasi:

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:nil)
self.navigationItem.rightBarButtonItem = b

Sekarang, saya ingin menelepon func sayHello() { println("Hello") }saat tombol disentuh. Upaya saya sejauh ini:

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:sayHello:)
// also with `sayHello` `sayHello()`, and `sayHello():`

dan..

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:@selector(sayHello:))
// also with `sayHello` `sayHello()`, and `sayHello():`

dan..

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:@selector(self.sayHello:))
// also with `self.sayHello` `self.sayHello()`, and `self.sayHello():`

Catatan yang sayHello()muncul di Intellisense, tapi tidak berhasil.

Terima kasih atas bantuan Anda.

EDIT: Untuk anak cucu, karya berikut:

var b = UIBarButtonItem(title: "Continue", style: .Plain, target: self, action:"sayHello")
kmiklas
sumber
4
Anda lulus penyeleksi dengan cepat hanya dengan meletakkan pemilih dalam string,action: "sayHello"
Jiaaro
Terima kasih banyak. Saya berada di bawah tekanan untuk mengeluarkan ini dan menjadi frustrasi.
kmiklas
1
Pertanyaan ini sebelumnya ditandai sebagai duplikat dari @selector () di Swift? . Namun, pertanyaan ini menanyakan secara khusus tentang UIBarButtonItemsementara yang lain tidak. Mewajibkan pemula untuk menggeneralisasi semua penggunaan selectorbisa sulit bagi mereka, jadi saya menghapus status duplikat sehingga orang dapat terus memperbarui pertanyaan ini.
Suragch

Jawaban:

157

Mulai dari Swift 2.2, ada sintaks khusus untuk pemilih yang diperiksa waktu kompiler. Ia menggunakan sintaks: #selector(methodName).

Swift 3 dan yang lebih baru:

var b = UIBarButtonItem(
    title: "Continue",
    style: .plain,
    target: self,
    action: #selector(sayHello(sender:))
)

func sayHello(sender: UIBarButtonItem) {
}

Jika Anda tidak yakin seperti apa nama metode itu, ada versi khusus dari perintah salin yang sangat membantu. Letakkan kursor Anda di suatu tempat di nama metode dasar (misalnya sayHello) dan tekan Shift+ Control+ Option+ C. Itu menempatkan 'Nama Simbol' pada keyboard Anda untuk disisipkan. Jika Anda juga menahannya, Commanditu akan menyalin 'Nama Simbol yang Memenuhi Syarat' yang akan menyertakan jenisnya juga.

Swift 2.3:

var b = UIBarButtonItem(
    title: "Continue",
    style: .Plain,
    target: self,
    action: #selector(sayHello(_:))
)

func sayHello(sender: UIBarButtonItem) {
}

Ini karena nama parameter pertama tidak diperlukan di Swift 2.3 saat melakukan panggilan metode.

Anda dapat mempelajari lebih lanjut tentang sintaks di swift.org di sini: https://swift.org/blog/swift-2-2-new-features/#compile-time-checked-selectors

menggambar
sumber
11
Sekadar menyebutkan bahwa fungsi tindakan tidak boleh bersifat pribadi ! Saya tidak begitu yakin mengapa, tetapi saya selalu mendapatkan kesalahan jika saya memberikan nama beberapa fungsi pribadi
maddob
Saya mendapatkan ini: "tidak mengimplementasikan methodSignatureForSelector"
AlamoPS
1
@AlamoPS Jika Anda menggunakan versi ke-2 dengan titik dua, Anda harus memastikan jenis parameter fungsi cocok untuk tindakan apa pun yang Anda tangani.
Jason
1
@RyanForsyth String sebenarnya diterjemahkan ke dalam di Selector("sayHello")balik layar oleh Swift.
fatuhoku
2
Jawaban ini sudah ketinggalan zaman.
Dan Loewenherz
34

Contoh Swift 4/5

button.target = self
button.action = #selector(buttonClicked(sender:))

@objc func buttonClicked(sender: UIBarButtonItem) {
        
}
norbDEV
sumber
5
Ini benar, untuk Swift 4 Anda perlu menambahkan @objcdeklarasi fungsi. Hingga Swift 4 ini secara implisit disimpulkan.
Jonathan Cabrera
1
button.target = self
Mahesh
@Mahesh tidak perlu menetapkan target
norbDEV
Target @norbDEV diperlukan untuk Swift 5
Biasi Wiga
3

Contoh Terprogram Swift 5 & iOS 13+

  1. Anda harus menandai fungsi Anda dengan @objc, lihat contoh di bawah ini!
  2. Tidak ada tanda kurung setelah nama fungsi! Gunakan saja #selector(name).
  3. privateatau publictidak penting; Anda dapat menggunakan pribadi.

Contoh Kode

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")
}
Zorayr
sumber
0

Semoga yang satu ini lebih membantu

Misalkan jika Anda ingin membuat tombol bilah dalam file terpisah (untuk pendekatan modular) dan ingin mengembalikan selektor ke viewcontroller, Anda dapat melakukan seperti ini: -

File Utilitas Anda

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

Kemudian buat kelas SuperviewController dan tentukan fungsi yang sama di atasnya.

class SuperViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
            // Do any additional setup after loading the view.
    }
    @objc func buttonClicked(sender: UIBarButtonItem) {

    }
}

dan Dalam viewController dasar kami (yang mewarisi kelas SuperviewController Anda) mengganti fungsi yang sama

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

Sekarang hanya mewarisi SuperViewController di kelas mana pun yang Anda inginkan barbutton ini.

Terima kasih sudah membaca

Anurag Bhakuni
sumber
0

Cepat 5

jika Anda telah membuat UIBarButtonItemdi Interface Builder dan Anda menghubungkan outlet ke item dan ingin mengikat selektor secara terprogram.

Jangan lupa tetapkan target dan selector.

addAppointmentButton.action = #selector(moveToAddAppointment)
addAppointmentButton.target = self

@objc private func moveToAddAppointment() {
     self.presenter.goToCreateNewAppointment()
}
Mahesh
sumber