ダウンロード サンプルファイル (68.6 KB)
本連載では、Swiftの基本的なプログラムができる読者を対象に、「Xcode 9」と「Swift 4」を使ってアプリを開発する際の基本的な内容である「Swiftでアプリ開発を行う上での基本的な記述の仕方や文法」「アプリの画面上での具体的な処理」「外部ライブラリを利用してアプリに機能を実装する方法」などを解説します。前回は、画面上のデータをやりとりする方法として最もよく利用されるデリゲートを使った処理を紹介しました。今回は、デリゲートよりも処理の記述がシンプルなプロパティを利用して画面上の処理を行う方法を説明します。
はじめに
Swift 4よりprivateで宣言されたプロパティも、extensionで分けたクラスから参照できることになったため、今回紹介するプロパティの機能はSwift 4からの機能として説明します。
本連載はアプリ開発の最初に知っておくべき基本的な事柄の説明をメインテーマとしています。内容によっては、Swift 4以前のバージョンに触れることや、Swift自体の言語仕様などには説明が及ばないこともご了承ください。本連載以上の各種情報は末尾の参考文献等を参照してください。
今回説明する具体的な内容は次の通りです。
- プロパティの値にクロージャを指定して画面をまたいだ処理を行う
- プロパティのwillSet/didSet関数を利用してUIを制御する
対象読者
本記事は、次の方を対象にしています。
- Swiftでの基本的なプログラムができる方
- Xcodeを使える方
クロージャを利用して処理を行う【Swift 4】
デリゲートは、自由に作成することができる汎用性の高い仕組みです。しかし、定義する部分と実行する部分が離れているため、いくつものデリゲートを使う場合にソースコードを追うのが手間になる場合もあります。また、利用する目的がひとつしかない場合などでは、デリゲートよりもシンプルに処理を実装したい場合もあります。このケースでは、デリゲートの代わりにクロージャを利用します。
Swift 3以降では、クロージャに関する強化された機能として次の2点が挙げられます。
- クロージャの引数にオプショナル型の変数が渡せるようになった
- ビューコントローラーのプロパティとしてクロージャの実装がサポートされた
サンプルを通して具体的な実装の例を解説します。
クロージャをプロパティとして定義する
前回のサンプルをデリゲートではなくクロージャを使って実装してみます。
前回作成した、デリゲートを利用するサンプルと同様の処理をクロージャを使って実装する場合、まずクロージャをプロパティで実装します。今回のサンプルでは、選択した項目をString型の変数で渡せるクロージャを、プロパティでアクセスできるように定義しています。
class MenuTableViewController: UITableViewController {
var completeSelect: ((String?) -> Void)?
...後略...
リスト1の通り引数と処理を表す「Void」を括弧で囲ってクロージャを定義します。クロージャを利用しない場合も考えられるため、後ろに「?」をつけてnullを考慮します。
さらに、クロージャの引数もオプショナル型で定義します。引数をオプショナル型にしておくことで、空の変数が渡された際にアプリがクラッシュしてしまうことを回避できます。
クロージャの処理内容を記述する
クロージャの処理内容は、インスタンスを生成する際に記述しています。サンプルでは、MenuTableViewControllerクラスのインスタンスを生成する際にクロージャの処理内容を記述しています。
@IBAction func onPressMenu(_ sender: Any) {
// Main.storyboardを取得
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
if let vc = storyBoard.instantiateViewController(withIdentifier:"MenuTableViewController") as?
MenuTableViewController {
vc.completeSelect = {
[weak self] (item) in
guard let word = item else { return }
self.label.text = "\(word)をクロージャで選択しました!"
}
self.present(vc, animated: true, completion: nil)
}
}
具体的には、ボタンを押してモーダルでテーブルを表示する際にクロージャの内容を記述しています。サンプルのようにクロージャの中で自分自身であるselfを参照すると、自分自身で指定したクロージャの中から自分自身を参照してしまう循環参照が発生します。それを防ぐために、クロージャの先頭でselfの前にweakをつけて弱参照で自分自身を参照するようにしておきます。その後、guard文でクロージャに渡された値が空だった場合、処理を抜けるようにします。最後にクロージャに渡された値を画面に表示します。
クロージャを実行する
ここまでの作業でクロージャを利用するための準備はできました。最後にセルの選択が行われた場合に、クロージャを実行する処理を記述します。
// テーブルのセル選択時の処理
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// IndexPathからセルを取得
let cell = tableView.cellForRow(at: indexPath)
if let text = cell?.textLabel?.text {
self.completeSelect?(text) // ------(1)
}
// モーダルを閉じる
self.dismiss(animated: true, completion: nil)
}
デリゲートでの処理と同様に、選択されたセルの項目名を取得します。取得した項目名を引数にしてクロージャを実行します(1)。
項目を選択した際に、選択した項目が画面に表示されることが確認できます。
この記事は参考になりましたか?
- Swift 4で最初に知っておきたい3つのポイント連載記事一覧
-
- Swift 4の外部ライブラリを利用して機能を実装する
- Swift 4における、プロパティを利用した処理とUIの制御
- Swift 4におけるオブジェクト間での相互作用
- この記事の著者
-
WINGSプロジェクト 片渕 彼富(カタフチ カノトミ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
