この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
こんばんは。モバイルアプリサービス部の平屋です。
「TableViewで入力フォームを作成する場合の実装」を簡単にしてくれるライブラリ「Eureka」を試してみましたので、その内容を紹介します。
「Eureka」を使用すれば、以下のスクショのような入力フォーム画面を簡単に作成できます。
検証環境
- macOS Sierra Version 10.12.5
- Xcode Version 8.3.2
目次
- 導入
- Eurekaを構成する主要コンポーネント
- 入力フォーム画面用のViewControllerの作成
- Section/Rowの追加
- Rowの値の取得
- Callback
- Section HeaderとFooterの設定
- 入力値のバリデーション
導入
CocoaPodsやCarthageなどを使用して導入できます。
// Podfileの作成例
use_frameworks!
target "EurekaSample" do
pod 'Eureka'
end
Eurekaを構成する主要コンポーネント
FormViewControllerのformプロパティに対して、SectionやRowを追加することによって、入力フォームを作成できます。
Form
- Eurekaの中心となるクラス
- 入力フォームを表す
- SectionやRowなどを管理する
FormViewController
- 入力フォーム画面を管理する
- UIViewControllerのサブクラス
- 以下のようなプロパティを持つ
var form: Form
var tableView: UITableView?
Section
- セクションを表す
- Rowを持つ
Row
- 行を表す
- 以下を持つ
- Value(入力/選択された値など)
- Cell(UITableViewCellのサブクラス)
- 入力フォーム作成時には、Rowのタイプごとに用意されているサブクラスを使用する
- 利用可能なRowの一覧
- 例
- TextRow: UITextfieldを持つRow
- Switch Row: UISwitchを持つRow
- Date Rows: UIDatePickerを持つRow
入力フォーム画面用のViewControllerの作成
FormViewControllerのサブクラスを作成します。
import UIKit
import Eureka
class ViewController: FormViewController {
// ...
}
Section/Rowの追加
カスタム演算子+++
を使用してSectionを、<<<
を使用してRowを追加できます。
class ViewController: FormViewController {
override func viewDidLoad() {
// ...
form
+++ Section()
<<< NameRow() {
$0.title = "Name"
}
}
}
カスタム演算子を使いたくない場合は、append
メソッドなどを使用してSection/Rowを追加できます。
class ViewController: FormViewController {
override func viewDidLoad() {
// ...
let row = NameRow() {
$0.title = "name"
}
let section = Section()
section.append(row)
form.append(section)
}
}
Rowの値の取得
Row作成時にタグを設定しておけば、あとから値を取得することができます。
NameRow("NameRowTag")
rowBy(tag:)メソッドを使用する
タグと共にFormのrowBy(tag:)
メソッドを使用すれば、対応するRowを取得し、Rowから値を取得することができます。
// Rowの値を取得する
let nameRow = form.rowBy(tag: "NameRowTag") as! NameRow
let name = nameRow.value!
values()メソッドを使用する
Formのvalues()
メソッドを使用すれば、タグが設定されている全てのRowの値を取得できます。
// タグ設定済みの全てのRowの値を取得
let values = form.values()
// Rowの値を取得する
let name = values["NameRowTag"] as! String
Callback
値変更時、Cell選択時などに実行したい処理があれば、処理をCallbackとしてRowに追加できます。
利用可能なCallback一覧はこちらにあります。
以下の例では、Rowの値が変更されたタイミングでログを出力しています。
form
+++ Section()
<<< NameRow() {
// ...
}.onChange {
print("Name changed:", $0.value ?? "");
}
Section HeaderとFooterの設定
Section作成時に、HeaderやFooterのタイトルを渡すと、タイトル付きのSectionを作成できます。
// Headerのタイトルだけを設定する
Section("Title")
// HeaderとFooterのタイトルを設定する
Section(header: "Title", footer: "Footer Title")
// Footerのタイトルだけを設定する
Section(footer: "Footer Title")
入力値のバリデーション
入力値のバリデーションを実行したい場合は、Rowにバリデーションのルールやオプションを追加します。バリデーション機能の詳細はこちらに記載されています。
以下の例では、NameRowに入力必須のルールを追加しています。値変更時に値が空だった場合、タイトルラベルの色が赤になります。
form
+++ Section()
<<< NameRow("NameRowTag") {
// ...
$0.add(rule: RuleRequired())
$0.validationOptions = .validatesOnChange
}.cellUpdate { cell, row in
if !row.isValid {
cell.titleLabel?.textColor = .red
}
}
また、Formのvalidate()
メソッドを使用すれば、入力フォーム全体に対してバリデーションを実行できます。
func didTapSaveButton(sender: UIBarButtonItem) {
let errors = form.validate()
guard errors.isEmpty else {
print("validate errors:", errors)
return
}
// ...
}
実装例
今回は、会員登録画面っぽいサンプルを作ってみました。
コードは以下のリポジトリで公開してます。
さいごに
本記事では、入力フォーム作成支援ライブラリ「Eureka」の概要を紹介しました。
テキストフィールドを持つセル、日付選択を提供するセルなどの、入力フォームを構成するセルをゼロから作るのは地味に手間がかかるので、とても便利だなと思いました!
本記事で紹介した機能以外にも、Eurekaは以下のような機能を提供してくれます。気になった方は、実際に試してみると良いかと思います。
- 複数の項目から選択させるためのセクションを作成する
- カスタムのセクションヘッダを追加する
- SectionやRowの表示/非表示切り替えを動的に行う
- 項目の追加、削除、並び替えを実行できるセクションを作成する
- カスタムのRowを作成する