*

Xcode6(Swift)のデリゲートとプロトコルの使い方

公開日: : 最終更新日:2014/10/21 Swift


スポンサードリンク



Xcode(Objective-C)のデリゲートの使い方[前編]では利用言語がObjective-Cの時のデリゲートの使い方の説明をさせていただきました。

本エントリーでは利用言語がSwiftの時のデリゲート(delegate)の使い方の説明をさせていただきます。

本エントリーの内容は以下の通りです。

  1. Xcodeにおけるデリゲートの説明
  2. 利用言語がSwiftの時のデリゲートの利用例

 

1 Xcodeにおけるデリゲートの説明

Xcode(Objective-C)のデリゲートの使い方[前編]では、Javaのインターフェースのようにまとまった機能に対応する処理を他のクラスに委譲すると説明させていただきました。

せっかくの別エントリーですので、もう少しインターフェースの説明を付け加えたいと思います。

広義のインターフェースとは

広義のインターフェースとは、界面や接触面、中間面などといった意味を持ち、転じてコンピュータと周辺機器の接続部分を表すようになっています。
さらに、ユーザーインターフェースなどのように、人間と自動機械との間の複雑な操作をする手順・規則との意味にも使われます。

狭義のインターフェースとは

JavaやC#等のプログラミング言語でインターフェースと言えば、メソッドの定義だけを行える物として認識されています。
抽象クラスと同じように、インターフェース自体はインスタンス化(実体化)できませんが、インターフェースを実装したクラスを
インターフェースとして操作できます。
(インターフェースに代入してとの意味です。)

インターフェースの例

インターフェースを説明する時によく利用される例として車があります。
車を例とした広義(一般的な意味)のインターフェースについて考えてみます。

車の機能として必須なのは、走る、止まる、まがるの3つです。
もっと具体的な処理としてとらえると

  • アクセル
  • ブレーキ
  • ハンドル

が広義のインターフェースと言えます。

これに対する狭義(プログラマブルな意味)のインターフェースは以下のようになります。

  • アクセルを踏んだ時の処理(runメソッド等)
  • ブレーキを踏んだ時の処理(brakeメソッド等)
  • ハンドルを操作した時の処理(handleメソッド等)

インターフェース自体は処理は存在しないメソッド定義だけが存在する物となります。

この3つの処理はどの車に乗っても基本的には同じ結果をもたらしますが、細かい内部処理は結構異なります。
(電気自動車だと加速が速い、排気量による加速の違い、ブレーキも各車によって利き方に相違がある等)
しかし、車を運転する人はアクセル、ブレーキ、ハンドルを操作することで車を動かすことはできます。

車の場合は絶対に許されないですが、
例えば、ブレーキを踏んだら走り出す。アクセルを踏んでも加速する。ハンドルを回すと反対方向にまがる。
みたいな内部処理にすることも可能です。

Javaの場合はインターフェースを実装するクラスを作成して、対応するインターフェースのメソッドの内部実装を行います。

Xcodeの場合もほぼ同じ考え方ですが、処理の委譲先クラス(インターフェースの実装クラスに相当)をデリゲート先としてセットしておくと

  • アクセルを踏んだら処理の移譲先クラスのrunメソッドが呼び出される。
  • ブレーキを踏んだら処理の移譲先クラスのbrakeメソッドが呼び出される。
  • ハンドルを操作したら処理の移譲先クラスのhandleメソッドが呼び出される。

のようなイメージで動作するようにできます。

Xcodeのプロトコルの利用

Xcodeでは、プロトコル(インターフェースに相当)を新しく定義して、デリゲート先のクラスを実装し、そのクラスを
処理の委譲先のクラスとしてセットすることで処理を実装します。詳細は後述させていただきます。

プロトコルの詳細な説明は「Xcode(Objective-C)のデリゲートとプロトコルの使い方[後編]」を参照ください。

Xcodeでは典型的な処理(GUI関係等)のプロトコルは全て言語側で用意されていますので、プロトコルを定義する必要はありません。
良く利用される例としては、

  • UIAlertViewDelegate(アラート画面の制御用プロトコル)
  • UITableViewDelegate(テーブルビューの制御用プロトコル)
  • UITableViewDataSource(テーブルビューのデータソースの制御用プロトコル)

等があります。

2 利用言語がSwiftの時のデリゲートの利用例

UIAlertViewDelegateの説明

iOS Developer Libraryの「UIAlertViewDelegate Protocol Reference」を例として進めます。
Objective-Cの説明資料ですが・・・

UIAlertViewDelegateは、アラート画面を表示する時の処理を実装できるように定義されたプロトコルです。
このプロトコル(インターフェース)に定義されている任意のメソッドを実装すると、アラート画面の任意の処理時に(ボタンタップ時等)呼び出されます。

このページで注目していただきたいのは「Tasks」です。
スクリーンショット 2014-03-24 17.39.31

画像に記載されているメソッドの概要は以下の様になります。

メソッド名 意味 UIViewContentMode
alertView(alertView: UIAlertView!, clickedButtonAtIndex buttonIndex: Int) イベントハンドラ ボタンがタップされた時に呼び出される。
alertViewShouldEnableFirstOtherButton(alertView: UIAlertView!) -> Bool 動作のカスタマイズ 右側のボタンを有効にするかしないかを決定する。有効にする場合はYESを返却
willPresentAlertView(alertView: UIAlertView!) 動作のカスタマイズ アラート表示直前に呼び出される。
didPresentAlertView(alertView: UIAlertView!) 動作のカスタマイズ アラート表示直後に呼び出される。
alertView(alertView: UIAlertView!, willDismissWithButtonIndex buttonIndex: Int) 動作のカスタマイズ アラート画面が閉じる直前に呼び出される。
alertView(alertView: UIAlertView!, didDismissWithButtonIndex buttonIndex: Int) 動作のカスタマイズ アラート画面が閉じた直後に呼び出される。
alertViewCancel(alertView: UIAlertView!) キャンセル時の動作 キャンセルされた時に呼ばれる。

UIAlertViewDelegateの説明アプリのプロジェクトの作成

プロダクト名:SwiftUIAlertViewDelegateSample
テンプレート:SingleView View Template
デバイス:iPhone
言語:Swift
を指定してプロジェックとを作成してください

タップ時にアラートを表示するボタンを配置

ボタンの配置やアウトレット、アクションの接続についての詳細は「Xcode5で画面コンポーネントを利用するための基本」をご覧ください。

アラート画面を呼び出すボタンの設置

Main.storyboardを開いて、ユーティリティエリアからボタンをドラッグ&ドロップします。
スクリーンショット 2014-08-28 15.54.30

アラート画面を呼び出すボタンのアウトレット接続

配置したボタンのアウトレット接続を行います。Nameはbuttonとしてください。

Buttonを選択し「Control」ボタンを押しながらViewControllerにドラッグ&ドロップします。
スクリーンショット 2014-08-28 19.08.51

Nameはbuttonを指定し「Connect」ボタンをクリックします。
スクリーンショット 2014-08-28 19.09.17

ViewControllerは以下のようになりました。

アラート画面を呼び出すボタンのアクションを追加

Buttonを選択し「Control」ボタンを押しながらViewControllerにドラッグ&ドロップします。
スクリーンショット 2014-08-28 19.18.09

ConnectionをActionに変更しNameにOnClickを指定して「Connect」ボタンをクリックします。
スクリーンショット 2014-08-28 19.34.50

ViewControllerに以下のメソッドが追加されました。

アラート画面の表示処理の追加とUIAlertViewDelegateの実装

ボタンタップ時のアラート画面の表示処理の追加

onClickメソッドを以下のように変更しました。
UIAlertViewDelegateのデリゲート先はまだ実装していませんがselfをセットしています。
よって、selfイコールViewControllerクラスでUIAlertViewDelegateを実装することを想定しています。

実行後にButtonをタップした時に表示される画面は以下のようになりました。
スクリーンショット 2014-08-28 21.30.05

UIAlertViewDelegateの実装の指定

先ほども記載いたしましたが、UIAlertViewのインスタンス作成時にデリゲート先にselfを設定しましたので
ViewControllerクラスでUIAlertViewDelegateを実装する必要があります。

Swiftにおけるプロトコルの実装には2つの手順を踏む必要があります。
1つ目は、対象プロトコルを実装するクラスであるとクラス宣言時に指定する。
2つ目は、対象プロトコルで実装したいメソッドを実装することです。

ViewControllerクラスがUIAlertViewDelegateプロトコルを実装するクラスであると指定するには
以下のように記載する必要があります。

UIViewControllerはViewControllerの基底クラスです。
実装するプロトコルが存在する場合は基底クラスの後ろにカンマ+実装するプロトコルとの記述を追加します。
実装するプロトコルが複数存在する場合はカンマ+実装するプロトコルの記述を複数追加します。

単純化した文字で表現すると以下のようになると思います。
class クラス名: 基底クラス名, プロトコルA, プロトコルB, プロトコルC

UIAlertViewDelegateの各メソッドをオーバーライド

UIAlertViewDelegateプロトコルの7つのメソッドは全てoptional(実装は任意)となっているため
必要なメソッドだけ実装すれば良いのですが、全て実装してみます。
といってもNSLogでログを吐き出すだけですが・・・

ViewControllerクラスは以下のようになりました。

実装後の動作時のログの確認

Buttonボタンをタップした時のログ

Buttonボタンをタップした時のログは以下のようになりました。

プロトコルの説明通りのタイミングで期待されるメソッドが呼び出されていることが確認できます。

アラート画面で2つ目のボタンのタイトルをタップした時のログ

アラート画面で2つ目のボタンのタイトルをタップした時のログは以下の通りです。

2つ目のボタンに対応するインデックスは1(0はキャンセルボタン)ですので、
呼び出されるメソッドの順番と表示されているインデックスが正しいことが確認できます。

アラート画面でキャンセルボタンのタイトルをタップした時のログ

キャンセルボタンに対応するインデックスは0固定ですので、
呼び出されるメソッドの順番と表示されているインデックスが正しいことが確認できます。

2つ目のボタンをタップした時とインデックスの値だけが異なっていることがこのログのポイントです。

「Xcode(Swift)のデリゲートとプロトコルの使い方」は以上です。

 
関連オススメ書籍


スポンサードリンク

Googleアドセンス

Googleアドセンス




関連記事

Swift入門(Xcode6のXCTestフレームワークで学ぶ) 第一回「Swiftの概要」 

Swiftの簡単な説明 アップルのiOS(iOS8以降)およびOS Xのためのプログラミング言語。

記事を読む

Xcode6の正式版がリリースされApp Storeからダウンロードしインストール可能になりました。

ついにSwiftが利用できるXcode6の正式版がリリースされました。 ブラウザからMac App

記事を読む

Xcode6(xcode_6_beta_7、Xcode 6 GM seed)のインストール方法

2014年9月22日追記 Xcode6の正式版がリリースされApp Storeからインストール可能

記事を読む

iOS(Xcode6とSwift)におけるマルチスレッド処理の実装方法その1[NSThreadクラスの簡単な利用例]

前回はObjective-CにおけるNSThreadクラスの簡単な利用例を取り扱いましたが今回は、ほ

記事を読む

iOS(Xcode6とSwift)におけるマルチスレッド(非同期)処理の実装方法その2[GCD(Grand Central Dispatch)の利用]

「iOS(Xcode6とSwift)におけるマルチスレッド処理の実装方法その1」ではNSThread

記事を読む

2014年の秋のAppleのプレスイベントとXcode6-beta-7のインストール方法

2014年の秋のAppleのプレスイベント いよいよAppleは、米国西海岸時間9月9日午前10時

記事を読む

Xcode6-Beta3でSwiftでBDDを行うためにQuickを導入し動作させる手順

Clone the repository Create a using Quick Pro

記事を読む

Swift(Xcode6-Beta2)でMagicalRecord関連の処理を含んだDAOクラスのユニットテスト(UnitTest:XCTestフレームワーク)を実装する時にハマった事

SwiftでMagicalRecord関連の処理を含んだDAOクラスを作成し、ユニットテスト(XCT

記事を読む

Xcode6-Beta3でSwiftでBDDを行うためにQuickを導入しようと思ったが、all-product-headers.yaml:4:13: error: Could not find closing ]!が発生する

そろそろQuickを利用しようと思いまたまたハマりました。というかハマり中です。 「Quick

記事を読む

Swift入門(Xcode6のXCTestフレームワークで学ぶ) 第二回「関数(メソッド)とクロージャーの利用方法」

前回はSwiftの概要をザックリと説明させていただきました。 今回は「メソッドの宣言方法」をよ

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

動画で英語を学習できるiOSの無料アプリCapTubeをリリースいたしました。

個人では初となるiOSアプリをリリースいたしました。 何度もリジ

no image
Ruby on rails4系でBootstrapを利用するためのtips

MacでRuby on rails4系のBootstrapを利用しよう

no image
Java、Eclipse、JUnit関連のエントリーの移行のお知らせ

Java、Eclipse、JUnit関連のエントリーは http:/

iOS8開発者向けお勧め本紹介[詳細! Swift iPhoneアプリ開発 入門ノート Swift 1.1+Xcode 6.1+iOS 8.1対応]

iOS7開発者向けお勧め本紹介を以前に紹介させていただきまいたが、今回

Swift入門(Xcode6のXCTestフレームワークで学ぶ) 第二回「関数(メソッド)とクロージャーの利用方法」

前回はSwiftの概要をザックリと説明させていただきました。 今

→もっと見る

Optimization WordPress Plugins & Solutions by W3 EDGE
PAGE TOP ↑