IBOutletとIBAction

本項は以下のページの説明を参考にさせていただきました。
ありがとうございます。
IBOutletとIBAction:関連付けでラクラクパーツを配置しよう | iPhoneアプリ開発大百科

IBとは

IBはInterface Builderの略です。
「マウスで直感的にパーツなどを配置できる便利ソフト」のようなものです。
つまり、画面のレイアウトを作成するとき、マウスの操作だけでできてしまうのです。
エンジニアの現場ではこの仕組みを使うことが主流のようです。

IB_01

IBOutlet

IBOutletとは、パーツ自体をプログラムで定義した変数に紐付けるものです。
StoryBoardやxibファイルでレイアウトを作っても、それをソースコードで使うことはできません。
なので、StoryBoardやxibファイルとソースコードを紐付けましょう。

以下のステップで紐付けていきます。

  • StoryBoard(またはxibファイル)でUIを設置する(UIの文字列などを設定をする)
  • ソースコードにStoryboardに設置したUIと紐づけるためのオブジェクトを定義する
  • StoryBoardからReferencing Outletsを設定してオブジェクトと紐づける

StoryBoard(またはxibファイル)でUIを設置する(UIの文字列などを設定をする)

まずはStoryBoardに画面に表示したいUIをドラッグ&ドロップで設置していきます。
基本的に自由ですが、例として画像のように設置しています。

StoryBoardを作る

ソースコードにStoryboardに設置したUIと紐づけるためのオブジェクトを定義する

Storyboardに設置したUIと紐づけるには、クラス変数を以下のサンプルコードのように定義してあげます。
変数定義の際、@IBOutletを頭につけてあげることで「これはStoryBoard(またはxibファイル)のUIと紐づけるものですよ」と宣言します。

import UIKit

class ViewController: UIViewController {
    @IBOutlet let titleLabel : UILabel!         // 何か入力してくださいのラベル
    @IBOutlet let inputTextBox : UITextField!   // テキストボックス
    @IBOutlet let nextButton : UIButton!        // 次へボタン
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

StoryBoardからReferencing Outletsを設定してオブジェクトと紐づける

では、実際にStoryboardに設置したUIとさきほど定義したオブジェクトを紐づけて編集してみましょう。
まずStoryboardを表示して、紐づけたいオブジェクトを選択し、そこで二本指タップをします。(Macの設定によりますが…)

すると、どのような紐付けをするか設定するウィンドウが表示されます。
そのなかでReffencing outletの丸から画像のようにUIViewControllerのところにドラッグしてください。

オブジェクトと紐付け1

すると、画像のようにViewControllerの中で、選択したオブジェクトと同じ型のオブジェクトの一覧が出てきます。
紐づけたいオブジェクトを選択しましょう。
(今回はUILabelを選択したので、ViewControllerクラスの中でUILabelに該当するオブジェクトが表示されます。今回はtitleLabelを選択します。)
するとReffencing outletの欄にオブジェクトが追加されていることが確認できます。

オブジェクトと紐付け2

オブジェクトと紐付け3

これでオブジェクトの紐付けは終わりです。
他のオブジェクトに対しても同様にできます。

では、以下のように紐づけたUIを編集してみましょう。

  • ラベルの背景色をオレンジにする
  • ラベルの文字列を「名前を入力してください」に変える
  • テキストフィールドのプレースホルダーを「名前」にする
  • ボタンの文字列を黒にする
  • ボタンの背景色を緑にする

編集する内容は以下の通りになります。

import UIKit

class ViewController: UIViewController {
    @IBOutlet var titleLabel : UILabel!         // 何か入力してくださいのラベル
    @IBOutlet var inputTextBox : UITextField!   // テキストボックス
    @IBOutlet var nextButton : UIButton!        // 次へボタン
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view, typically from a nib.
        
        self.titleLabel?.text = "名前を入力してください"
        self.titleLabel?.backgroundColor = UIColor.orange
        self.inputTextBox.placeholder = "名前"
        self.nextButton?.setTitleColor(UIColor.black, for: UIControlState.normal)
        self.nextButton.backgroundColor = UIColor.green
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

実行するとこのような感じ。
確かに反映されていますね!

IBOutlet実行結果

IBAction

IBActionとは、パーツに何か変化を加えたときの動作をプログラムへ引き渡すものです。
つまり、「タップやスクロールなどした時にどういう動作をするのかをソースコードと紐づける」といった感じです。
今回は主に使われる例として、「ボタンをタップ時するとソースコードに紐づけたメソッドが実行される」ということを実装して行きます。

ステップは以下の通りです。

  • ボタンなど、イベントを発生させるUIを設置する
  • ソースコードにStoryboardに設置したUIと紐づけるためのメソッドを定義する
  • StoryBoardからSent Eventsのうちどれかを設定してメソッドと紐づける

ボタンなど、イベントを発生させるUIを設置する

これに至ってはIBActionのStoryBoard

ソースコードにStoryboardに設置したUIと紐づけるためのメソッドを定義する

イベントの処理内容を定義するメソッドをStoryboardに設置したUIと紐づけるには、
サンプルコードのようにメソッドを定義してあげます。
メソッド定義の際に、@IBActionを頭につけてあげることで「これはStoryBoard(またはxibファイル)のUIと紐づけるメソッドですよ」と宣言します。

そして、それをコードにすると以下のようになります。

import UIKit

class ViewController: UIViewController {
    @IBOutlet var titleLabel : UILabel!         // 何か入力してくださいのラベル
    @IBOutlet var inputTextBox : UITextField!   // テキストボックス
    @IBOutlet var nextButton : UIButton!        // 次へボタン
    @IBOutlet var inputTextLabel : UILabel!     // テキストボックスに入力した文字列を表示するラベル
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view, typically from a nib.
        
        self.titleLabel?.text = "名前を入力してください"
        self.titleLabel?.backgroundColor = UIColor.orange
        self.inputTextBox.placeholder = "名前"
        self.nextButton.titleLabel?.tintColor = UIColor.black
        self.nextButton?.setTitleColor(UIColor.black, for: UIControlState.normal)
        self.nextButton.backgroundColor = UIColor.green
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // ボタンが押されたら入力された文字列をラベルに表示するメソッド
    @IBAction func displayInputText() {
        self.inputTextLabel?.text = self.inputTextBox?.text
    }
}

StoryBoardからSent Eventsのうちどれかを設定してメソッドと紐づける

これもIBOutletでやったことと似たことをします。
今回は画像を中心に説明して行きます。

紐づけたいオブジェクトを選択し、そこで二本指タップをします。
すると、以下のようにウィンドウが表示されます。

IBAction01

ここでちょっと違うのが、今回はSend Eventうち、設定したいイベントの丸の部分からUIViewControllerへドラッグしてください。
今回はボタンをタップし、指を話したタイミングでメソッドを呼び出したいので「Touch Up Inside」の丸の部分からドラッグします。

IBAction02

今回、紐づけたいメソッドはソースコードの通り、「displayInputText」なのでそれを選択します。

IBAction03

では、動作確認をしてみましょう。
以下の画像のように入力し、「次へ」ボタンをタップすると…
IBAction_test01

ラベルが表示されるのがわかります。
お疲れ様です。
IBAction_test02

IBOutletとIBActionに関しては以上です。
お疲れ様です!

ちなみに、Storyboardやxibファイルを使う開発をするなら、Autolayoutも一緒に勉強しておいてください。
画面の大きさが異なる場合でもイメージ通りの画面のレイアウトを作るのに必ず必要になります。

個人的に

C言語でシューティングゲームを作ってた頃は、何をどこに表示するかを全てソースコードから制御していたので、僕はあまり好きではなかったです。

しかし、開発の現場ではIBを使うというのが主流のようです。

いざIBでやってみると随分と苦戦したときはありますが、正直IBを使う方が楽です。
理由は以下のような感じです。

  • 視覚的にレイアウトがわかるのでメンテナンスしやすい
  • Autolayoutを使って大きさが違う端末にも対応しやすい

現場でも使われているので、是非IBを勉強してください。
といっても、ソースコードのみで書くことにこだわる人はあまりいないかもしれませんが…(^^;