24/7 twenty-four seven

iOS/OS X application programing topics.

Auto Layoutの静的な制約で実現するテキストの量によって折りたたみ可能なテキストビュー

長いテキストが初期表示では折りたたまれて表示されていて、「つづきを読む」ボタンを押すことで表示エリアが拡大して全文が表示されるという挙動を、できるだけ動的な要素を排除して実現してみます。


f:id:KishikawaKatsumi:20181105035723g:plain:w320


サンプルコードは下記のリポジトリで公開しています。

github.com


今回の例ではUIStackViewを活用します。UIStackViewは内部のビューのisHiddenプロパティによってビューのサイズをゼロにできるので、うまく活用すればあたかも複数のレイアウトを切り替えているような挙動を実現できます。

テキストビュー(またはラベル)の左右両端と上端が一致するようにStack Viewに制約を付けます。

さらにテキストビューとStack Viewの高さが一致する制約を付けます。

Stack Viewの中のビューに高さの制約として折りたたんだときのサイズを指定します。例では200ptです。 テキストの分量がその高さに満たない場合はテキストの高さに合わせるべきですので、制約は等号ではなく以下を示す(<=)にしておきます。

これでテキストビューとまったく同じ位置にStack Viewが表示されます。


f:id:KishikawaKatsumi:20181105042813p:plain

Storyboardで作っている場合はここでStack Viewの中のビューのisHiddenプロパティを切り替えてみましょう。

isHiddentrue(チェック)にすると、テキストビューが本来のサイズまで高さが伸びることがわかります。

Stack Viewの中のビューのisHiddentrueになることで、Stack ViewのIntrinsic Content Sizeがゼロになります。そのため最終的にテキストビュー自身の高さにAuto Layoutが解決されます。テキストビューとStack View間の制約は、高さが同じというものですので、その場合でも問題なく制約を満たすことができています。


Stack Viewの便利な点はこのようにビューと制約の有効化・無効化をisHiddenのプロパティだけで行えることにあります。 アクションや状態の変化をisHiddenのON/OFFにマッピングすることで宣言的に異なるレイアウトに切り替えることができます。

このテクニックも応用範囲が広いので使いこなせると便利です。 下記の記事と合わせてご覧ください。

blog.kishikawakatsumi.com