Edited at

[iOS]カスタマイズ可能なUIButton風のCustomViewを作ってみました


コード

https://github.com/osanaikoutarou/ButtonView


モチベーション

UIButtonをカスタマイズしようとした時、どうするでしょうか?

UIButtonはInterfaceBuilder上で、子Viewを置けません。


  1. UIButtonのパラメータをいじって頑張る

  2. すべて画像にしてしまう

  3. UIButtonにaddSubviewしてしまう

  4. Viewの上に、同じ大きさの透明なUIButtonを置く

  5. UIGestureRecognizerを使う

  6. UIButtonの親クラスであるUIControlをカスタマイズする

今回は、6を作ってみました。

利点:InterfaceBuilder上でButtonの中身に対してAutoLayoutを組める。


動き

こんな感じです。すべてUIControlのサブクラスです。

ButtonView1edit.gif

Type
見た目

componentLight
子Viewを薄くする

componentDark
Label以外を暗くする

baseDark
全体を暗くする

lighterTheWhole
全体の半透明にする

likeButtonPlane
通常のUIButton状態 ラベルだけ薄くなる

likeButtonCustom
通常のCustomUIButton状態 Imageが暗くなる

whiteTheWhole
全体が白くなる

他にも柔軟にカスタマイズできます

ButtonView2edit.gif

selected,disable,highlightのViewをセットできます

ButtonView3edit.gif

ボタンとの比較です。似せています。

ButtonView4edit.gif

画像ボタンも簡単です。

角丸の場合は、WhiteやDarkがその形に沿っています(重要)


類似ライブラリはないのか?

私は探せませんでした。

もっと具体的な「よく使うボタン」をまとめたものはあります。


使い方

スクリーンショット 2018-10-07 17.08.25.png

UIViewにButtonViewをClass指定してください。

UIControlでもいいですが。

そうすればいつものアレが出ます。

スクリーンショット 2018-10-07 17.09.21.png

ボタンはタイプの設定が必要です。デフォルトではUIButtonっぽくなります。

inuButton.setup(type: .darkerTheWhole)

特定のStateに対するViewを設定する場合は以下です。あまり使わないですけど。

inuButton.setView(view: pressedInuButton, forState: .highlighted)

あまりViewの階層を深くしたり、複雑なViewを組み込んだ場合は想定していないのでどうなるかわかりません。

StackViewくらいならどうにかなると思います。


実装の中身

目標としては、UIControlとUIButtonの差分を埋めるだけです。

ただし今回はTitleやImage、BacgroundImageは不要です。

あと細かなShadowの仕様とか、Insetの仕様は詰めていません(完全に自分が普段使っていない仕様を無視している状態)

TODO一覧


  • タッチした際に表示を変える


    • 表示パターンのルールを作る(UIButtonに存在しないパターンもあるので)



  • 範囲を外れた時、範囲に戻ったときに表示を変える

  • selected,highlight,disableの時のViewをセットできるようにする

実は、イベント関連はUIButtonじゃなく、UIControlなんですよね(知らなかった)

UIControlStateはもちろんUIControlの仕様なんですが、setImage:forStateとかはUIButtonの仕様です(解せない。もしくは私が知らないだけか)

実際のコードに関しては特に面白くないので割愛します。


所感、その他

3 UIButtonにaddSubviewしてしまう

4 Viewの上に、同じ大きさの透明なUIButtonを置く

こっちの方でも似たことできそうなんですが、3はやはりInterfaceBuilderでレイアウトが組めませんし、4はイベントとの繋ぎ込みができないので使い勝手が悪そうです。

実際に半年くらい使っていますが、痒いところに手が届く感じが気に入っています。

よく「そのボタンの仕様って、iOS的じゃないんですよね〜〜」とか以前は言ってましたがもう言いません。

iconをどの位置にどの大きさで置くとかにも悩みません。

ボタンの中でアニメーションも簡単です。

あと残す面倒事はシャドーくらいです・・・