LoginSignup
6
6

More than 5 years have passed since last update.

swiftで、タンポポのせみたいな設定作業をクロージャ使って見やすくする

Last updated at Posted at 2014-11-28

swiftのクロージャを使って設定情報を書きたい

他言語では設定をクロージャを使って書いたりするので、その流れでやってみた。
(ちなみにswiftは一昨日から触り始めて、知識はほぼwikiから)

やりたいこと

いま、たくさんのページにUITextFeildをデザインに従っていっぱい埋め込むという、タンポポのせみたいな仕事をしている。
storyboardを使わずに。

どういう仕事かというと、ページ全部で100ページあるとすると、10ページずつ、大まかにUITextFieldの設定が違う。
そして、1ページの中にあるいくつかのUITextFieldの設定はさらに細かく違う。

こうなると、UITextFieldを生成するのに、さすがに毎回以下のように書くわけにはいかない。

let textField = UITextField()
textField.borderStyle = UITextBorderStyle.RoundedRect // 枠
textField.font = UIFont.systemFontOfSize(15) // フォントサイズ変える
textField.textColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // 色を変える
textField.placeholder = "ここに書き込んでください"
textField.textAlignment = NSTextAlignment.Center // 中央寄せする
// 次は文字が入るぴったりのサイズに変えて、次は...etc

くくり出す

普通に考えて、共有できる部分をくくり出してみる。
100ページのうち、10ページずつで固定されるものは、(ここでは例として)borderStyleとtextAlignmentとする。
buildTextField()というメソッドを作って、そのへんのクラスに放り込んでおいた(適当)。

class UIBuilder {
    class func buildTextField() -> UITextField {
        let textField = UITextField()
        textField.borderStyle = UITextBorderStyle.RoundedRect // 枠
        textField.textAlignment = NSTextAlignment.Center // 中央寄せする
        return textField
    }
}

呼び出す。

let textField = UIBuilder.buildTextField()
textField.font = UIFont.systemFontOfSize(15) // フォントサイズ変える
textField.textColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // 色を変える
textField.placeholder = "ここに書き込んでください"

これだけでも、タンポポのせがちょっと楽になる。
UITextFieldの生成と一部の設定が隠蔽されているので、知らない人が読んだ時に若干戸惑いが発生する可能性があるけど、背に腹はかえられない。

カオス

現実のタンポポのせは辛いもの。

最初の例は問題を簡単にするために、TextFieldが1個しかないことになっているけど、当然1ページの中に複数ある。
そうなると、ソース上で1つ1つのtextFieldを判別できる変数名にする必要がある。

…あるよね?
さすがに、textField1とかtextField2とかいう変数にすると、後で見た時に辛いと思ってくれるよね?

とりあえず辛いということにして、意味のある名前をつける必要がある。
「えーと、この画像の上にある、この四角の中の、このラインの上で、隣に丸がある…」みたいな名前をつける。
そう、textFieldOnHogeInPiyoUnderFugaWith...みたいな名前をつけるんだ…!

このへんでstoryboardに帰りたくなったけど、我慢した。
さて、素直に書いてみましょう。

let textFieldOnHogeInPiyoUnderFuga = UIBuilder.buildTextField()
textFieldOnHogeInPiyoUnderFuga.textColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // 色を変える
textFieldOnHogeInPiyoUnderFuga.placeholder = "ここに書き込んでよね"
// ほか3行ほど設定

let textFieldOnHogeraInPiyoUnderFuga = UIBuilder.buildTextField()
textFieldOnHogeraInPiyoUnderFuga.font = UIFont.systemFontOfSize(15) // フォントサイズ変える
textFieldOnHogeraInPiyoUnderFuga.placeholder = "ここに書き込むべき"
// ほか4行ほど設定


// あと5個だよ!

いや…わかる…わかるよ。
所謂クソコードってやつね。わかる。あれね。

1行が長すぎるし、タイプミス(Xcodeだから補完ミスか)してても正直わからん。

クロージャによる設定

名前はしょうがないとして、できるならその変数の使用回数を減らしたい。あと、もうちょっと明示的にまとまりを示したい。
ので、

class UIBuilder {
    class func buildTextField(settingFunc: (UITextField)->Void) -> UITextField {
        let textField = UITextField()
        textField.borderStyle = UITextBorderStyle.RoundedRect // 枠
        textField.textAlignment = NSTextAlignment.Center // 中央寄せする
        settingFunc(textField)
        return textField
    }
}

とクロージャを受けるようにしておいて、

let textFieldOnHogeInPiyoUnderFuga = UIBuilder.buildTextField() { f in
    f.textColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // 色を変える
    f.placeholder = "ここに書き込んでよね"
    // ほか3行ほど設定
}

let textFieldOnHogeraInPiyoUnderFuga = UIBuilder.buildTextField() { f in
    f.font = UIFont.systemFontOfSize(15) // フォントサイズ変える
    f.placeholder = "ここに書き込むべき"
    // ほか4行ほど設定
}

とする。

これでタンポポが綺麗にのせられるようになった。
速くなったり、すごく事故が減るとか、そういうメリットがある書き方ではないんだけど、見やすい。
見やすいのはメンテしやすい。

なお、現実のコードでは、第一引数のクロージャは省略可能にしないと空のクロージャを登録する場面がでてくる。
この例だと必要性がないので書いてない。

余談

例えばRubyでは、同様にクロージャを使って設定情報を入れるというのは良く見る。

foo = Foo.build() { |setting|
  setting.hoge = true
  setting.fuga = false
}

けれど、こうするより

foo = Foo.build( {
  hoge: true,
  fuga: false
})

と書いた方が、後者の方が自由度が少なくてハマることが多いと個人的には思う(ここまで書いといてなんだが)。

前者のようにクロージャで書くと、中に何でも書けるので、クロージャ内部で書いた方が良いことと、外で書いた方が良いことが曖昧になる。
上の例だと、意図としてはbuild()するのに必要な補足情報をクロージャで入れる、という感じで書いたのだろうけど、build()した後にゴニョゴニョするようなコードを入れてしまう事がある。

TODO: この部分をswiftで書き直す。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6