Swiftでタグを入力するUIを作ったやつ

タグを入力するViewを作った

以前に下のようなタグを入力する画面を作成したのですが、これもアウトプットしないと勿体ない系だと思ったので簡単にまとめます。

f:id:churabou:20190904230345g:plain

類似するUIを持つ具体的なアプリがすぐには思いつかないのですが、日記アプリやメモアプリなどタグを入力するUIは存在すると思います。 このような他のアプリで使えそうなコンポネントを公開する際は、どこまでカスタマイズ可能にし、どのようなインターフェースで公開するのか決めるのが凄く難しいです。 それでも悩んで公開しないよりは妥協して公開したほうがいいと思うのでまとめます。

使い方

普通に初期化して使えます。

let tagField = TagFieldView()

引数はこんな感じです。

    init(
        placeholderText: String = "tags",
        defaultTags: [String] = [],
        tagViewStyle: TagView.Style = .init()
        layout: TagLayoutView.Layout = .init(margin: Margin(x: 8, y: 4)),
        validator: TagValidator = DefaultTagValidator()
     )

placeholderTextと初期値のタグ(編集画面で使う場合は既にタグの入力がある)とタグの見た目とレイアウトオブジェクトとValidatorです。 Validatorは入力されたタグの検証をするためのものです。Defaultクラスはタグが重複しないように実装しています。

struct DefaultTagValidator: TagValidator {
    func validate(tag: String, tags: [String]) -> Bool {
        return !tags.contains(tag) && !tag.isEmpty
    }
}

例えば禁止ワードを排除したりDB内に存在しないものみの入力を受け付けるなどが想定できたので外出しにしました。 また編集画面など初期値でタグを入れる場合にも同様のvalidationが走ります(初期値とし重複したタグを入れられることに実装中に気付いた)

実装方針

Styleを外から決めて、UIイベントをクロージャーで公開するTagViewクラスやタグを並べるだけのTagLayoutViewクラスなど 軽めのクラスを作成し、それを親クラスのTagFeildが管理する実装にしました。 結果的にテキストの検証の部分や並べ替えの処理などがしっかり分けられていて良かったと思います。 またレイアウト用のクラスがLayoutオブジェクトを使って描画するようにしているため、タグの並べ方を例えば中央寄せにするなどといった拡張もしやすくなりました。(Layoutクラスにalignmentプロパティーを追加してLayoutクラスでそれを考慮して並べ替えるように追加する)

UI/UIX??

  • Deleteキーを押すと一回目で直前の入力タグがハイライトされ二回目で削除されます。すでに選択されたタグがある場合はそれが削除されます。
  • 選択時にはアニメーションと透明度を変えて分かるようにしてます。

感想

Textfieldの見た目、タグが選択された時の見た目、削除ボタンの見た目などはハードコードしています。 見た目のカスタマイズ性は中途半端に妥協しました。というか別にライブラリを作ったわけではない。

個人で使う分に作るのは簡単だったけど、公開するために色々考えるのはかなり時間がかかってしんどかったです。