Cách đặt hành động cho UIBarButtonItem trong Swift


86

Làm cách nào để thiết lập hành động cho UIBarButtonItem tùy chỉnh trong Swift?

Đoạn mã sau đặt thành công nút vào thanh điều hướng:

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

Bây giờ, tôi muốn gọi func sayHello() { println("Hello") }khi nút được chạm vào. Những nỗ lực của tôi cho đến nay:

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

và ..

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

và ..

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

Lưu ý sayHello()xuất hiện trong intellisense, nhưng không hoạt động.

Cảm ơn bạn đã giúp đỡ.

CHỈNH SỬA: Đối với hậu thế, các tác phẩm sau:

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

4
bạn vượt qua selectors trong nhanh chóng bằng cách chỉ đặt bộ chọn trong một chuỗi,action: "sayHello"
Jiaaro

Cảm ơn bạn rất nhiều. Tôi bị áp lực phải giải quyết vấn đề này và rất thất vọng.
kmiklas

1
Câu hỏi này trước đây đã được đánh dấu là bản sao của @selector () trong Swift? . Tuy nhiên, câu hỏi này hỏi cụ thể về vấn đề UIBarButtonItemtrong khi câu hỏi kia thì không. Việc yêu cầu người mới bắt đầu khái quát tất cả các cách sử dụng selectorcó thể khó khăn đối với họ, vì vậy tôi sẽ xóa trạng thái trùng lặp để mọi người có thể cập nhật câu hỏi này.
Suragch

Câu trả lời:


157

Kể từ Swift 2.2, có một cú pháp đặc biệt cho các bộ chọn kiểm tra thời gian biên dịch. Nó sử dụng cú pháp: #selector(methodName).

Swift 3 trở lên:

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

func sayHello(sender: UIBarButtonItem) {
}

Nếu bạn không chắc tên phương thức trông như thế nào, có một phiên bản đặc biệt của lệnh sao chép rất hữu ích. Đặt con trỏ của bạn ở đâu đó trong tên phương thức cơ sở (ví dụ: sayHello) và nhấn Shift+ Control+ Option+ C. Điều đó đặt 'Tên biểu tượng' trên bàn phím của bạn sẽ được dán. Nếu bạn cũng giữ Commandnó, nó sẽ sao chép 'Tên Ký hiệu Đủ điều kiện' và cũng sẽ bao gồm cả loại.

Swift 2.3:

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

func sayHello(sender: UIBarButtonItem) {
}

Điều này là do tên tham số đầu tiên không được yêu cầu trong Swift 2.3 khi thực hiện một cuộc gọi phương thức.

Bạn có thể tìm hiểu thêm về cú pháp trên swift.org tại đây: https://swift.org/blog/swift-2-2-new-features/#compile-time-checked-selectors


11
Chỉ cần đề cập rằng chức năng hành động không thể là riêng tư ! Tôi không thực sự chắc chắn lý do tại sao, nhưng tôi luôn luôn nhận được một lỗi trong trường hợp tôi cung cấp tên của một số chức năng riêng
maddob

Tôi nhận điều này: "không thực hiện methodSignatureForSelector"
AlamoPS

1
@AlamoPS Nếu bạn đang sử dụng phiên bản thứ 2 có dấu hai chấm, bạn sẽ cần đảm bảo rằng các loại tham số hàm phù hợp với bất kỳ tác vụ nào bạn đang xử lý.
Jason

1
@RyanForsyth Dù sao thì chuỗi ký tự này cũng được Selector("sayHello")Swift dịch sang hậu trường.
fatuhoku

2
Câu trả lời này đã lỗi thời.
Dan Loewenherz

33

Swift 4/5 ví dụ

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

@objc func buttonClicked(sender: UIBarButtonItem) {
        
}

5
Điều này đúng, đối với Swift 4 bạn cần thêm @objcvào phần khai báo hàm. Cho đến Swift 4, điều này đã được suy luận ngầm.
Jonathan Cabrera

1
button.target = self
Mahesh

@Mahesh không cần đặt mục tiêu
norbDEV

Mục tiêu @norbDEV là cần thiết cho Swift 5
Biasi Wiga,

2

Ví dụ về Swift 5 & iOS 13+ có lập trình

  1. Bạn phải đánh dấu chức năng của mình bằng @objc, xem ví dụ dưới đây!
  2. Không có dấu ngoặc đơn sau tên hàm! Chỉ cần sử dụng #selector(name).
  3. privatehay publickhông quan trọng; bạn có thể sử dụng riêng tư.

Ví dụ về mã

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

0

Mong điều này giúp đỡ nhiều hơn một chút

Giả sử nếu bạn muốn tạo nút thanh trong một tệp riêng biệt (đối với phương pháp mô-đun) và muốn đưa bộ chọn trở lại bộ điều khiển chế độ xem của mình, bạn có thể làm như sau: -

Tệp Tiện ích của bạn

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

Sau đó tạo một lớp SuperviewController và xác định cùng một chức năng trên nó.

class SuperViewController: UIViewController {

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

    }
}

và Trong viewController cơ sở của chúng tôi (kế thừa lớp SuperviewController của bạn) ghi đè cùng một chức năng

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

Bây giờ chỉ cần kế thừa SuperViewController trong bất kỳ lớp nào bạn muốn nút này.

Cảm ơn vì đã đọc


0

Swift 5

nếu bạn đã tạo UIBarButtonItemtrong Trình tạo giao diện và bạn đã kết nối đầu ra với mục và muốn liên kết bộ chọn theo chương trình.

Đừng quên đặt mục tiêu và bộ chọn.

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

@objc private func moveToAddAppointment() {
     self.presenter.goToCreateNewAppointment()
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.