SwiftでUIBarButtonItemのアクションを設定する方法


86

SwiftのカスタムUIBarButtonItemのアクションをどのように設定できますか?

次のコードは、ボタンをナビゲーションバーに正常に配置します。

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

さて、func sayHello() { println("Hello") }ボタンをタッチしたときに電話をかけたいと思います。これまでの私の努力:

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

そして..

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

そして..

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

sayHello()これはインテリセンスに表示されますが、機能しないことに注意してください。

ご協力いただきありがとうございます。

編集:後世のために、次の作品:

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

4
セレクターを文字列に入れるだけで、セレクターをaction: "sayHello"
すばやく

どうもありがとうございます。私はこれを取り除くようにプレッシャーを受けており、イライラしていました。
kmiklas 2014

1
この質問は以前、Swift@selector()の重複としてマークされていましたか?。ただし、この質問は具体的に質問しますがUIBarButtonItem、他の質問は質問しません。初心者にすべての使用法を一般化するように要求するselectorことは彼らにとって難しい場合があるので、人々がこの質問を最新に保つことができるように、私は重複ステータスを削除しています。
suragch 2016年

回答:


157

Swift 2.2以降、コンパイラー時にチェックされるセレクターには特別な構文があります。構文を使用します:#selector(methodName)

Swift 3以降:

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

func sayHello(sender: UIBarButtonItem) {
}

メソッド名がどのように表示されるかわからない場合は、非常に役立つ特別なバージョンのcopyコマンドがあります。基本メソッド名(例のsayHello)と押しでカーソルのどこかに置きます Shift+ Control+ Option+をC。これにより、キーボードの「記号名」が貼り付けられます。保持しCommandている場合は、タイプも含まれる「修飾記号名」がコピーされます。

Swift 2.3:

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

func sayHello(sender: UIBarButtonItem) {
}

これは、Swift 2.3では、メソッド呼び出しを行うときに最初のパラメーター名が必要ないためです。

swift.orgの構文について詳しくは、https://swift.org/blog/swift-2-2-new-features/#compile-time-checked-selectorsをご覧ください。


11
アクション関数をプライベートにすることはできません。理由はよく
わかりません

私はこれを手に入れました:「
methodSignatureForSelectorを

1
@AlamoPSコロン付きの2番目のバージョンを使用している場合は、処理するアクションの関数パラメータータイプがそれに一致することを確認する必要があります。
ジェイソン

1
@RyanForsythとにかく、文字列は実際にはSelector("sayHello")Swiftによって舞台裏に翻訳されます。
fatuhoku 2015

2
この答えは時代遅れです。
Dan Loewenherz 2016

33

Swift4 / 5の例

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

@objc func buttonClicked(sender: UIBarButtonItem) {
        
}

5
これは正しいです。Swift4の場合@objc、関数宣言に追加する必要があります。Swift 4までは、これは暗黙的に推測されていました。
ジョナサンカブレラ

1
button.target = self
マヘシュ

@Maheshはターゲットを設定する必要はありません
norbDEV

@norbDEVターゲットはSwift5
Biasi

2

Swift5およびiOS13 +のプログラム例

  1. 関数をマークする必要があります @objcで。以下の例を参照してください。
  2. 関数名の後に括弧はありません!を使用するだけ#selector(name)です。
  3. privateまたは関係ありpublicません。プライベートを使用できます。

コード例

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

これがもう少し助けになりますように

バーボタンを別のファイルで作成し(モジュラーアプローチの場合)、セレクターをビューコントローラーに戻したい場合は、次のように実行できます:-

ユーティリティファイル

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

次に、SuperviewControllerクラスを作成し、同じ関数を定義します。

class SuperViewController: UIViewController {

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

    }
}

ベースのviewController(SuperviewControllerクラスを継承)では、同じ関数をオーバーライドします

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

ここで、このバーボタンが必要なクラスのSuperViewControllerを継承するだけです。

読んでくれてありがとう


0

スウィフト5

作成した場合 UIBarButtonItemInterface Builderで、コンセントをアイテムに接続していて、セレクターをプログラムでバインドしたい場合。

ターゲットとセレクターを設定することを忘れないでください。

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

@objc private func moveToAddAppointment() {
     self.presenter.goToCreateNewAppointment()
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.