Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

Swift 4における、プロパティを利用した処理とUIの制御

Swift 4で最初に知っておきたい3つのポイント 第4回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2018/02/19 14:00

 本連載では、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型の変数で渡せるクロージャを、プロパティでアクセスできるように定義しています。

リスト1 MenuTableViewController.swift
class MenuTableViewController: UITableViewController {
    
    var completeSelect: ((String?) -> Void)?
...後略...

 リスト1の通り引数と処理を表す「Void」を括弧で囲ってクロージャを定義します。クロージャを利用しない場合も考えられるため、後ろに「?」をつけてnullを考慮します。

 さらに、クロージャの引数もオプショナル型で定義します。引数をオプショナル型にしておくことで、空の変数が渡された際にアプリがクラッシュしてしまうことを回避できます。

クロージャの処理内容を記述する

 クロージャの処理内容は、インスタンスを生成する際に記述しています。サンプルでは、MenuTableViewControllerクラスのインスタンスを生成する際にクロージャの処理内容を記述しています。

リスト2 MenuTableViewController.swift
@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文でクロージャに渡された値が空だった場合、処理を抜けるようにします。最後にクロージャに渡された値を画面に表示します。

クロージャを実行する

 ここまでの作業でクロージャを利用するための準備はできました。最後にセルの選択が行われた場合に、クロージャを実行する処理を記述します。

リスト3 MenuTableViewController.swift
// テーブルのセル選択時の処理
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)。

サンプルの実行結果
サンプルの実行結果

 項目を選択した際に、選択した項目が画面に表示されることが確認できます。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 片渕 彼富(カタフチ カノトミ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:Swift 4で最初に知っておきたい3つのポイント
All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5