動作環境
- Swift 5.2
- Xcode 11.5
つくるやつ
こんな風にボタンを押したらUILabelが開閉するサンプルを作ります。開閉したいラベルの入ったUIStackViewと、閉じているときの高さを持ったUIViewの入ったUIStackViewを準備して、2つのUIStackViewの高さが同じになるような制約をつけておくことで、view.isHiddenの切り替えで開閉できるようになります。
文章はこちらから拝借しました。

Storyboardのつくり方
手順
-
可変したい
UILabelを準備してUIStackView(以下、TitleContainerViewと呼びます)に内包します。当然ですがnumberOfLinesは0に設定する必要があります。
TitleContainerViewの設定は、Axis: Vertical、Alignment: Center、Distribution: Fillとします。

-
もっと見るボタンを配置して、
TitleContainerViewのbottomに紐付けます。こうすることで、TitleContainerViewが広がった時に一緒に下へ動くようになります。

-
もう1つ
UIStackViewを準備して、中に空のUIViewを配置します。このUIStackViewの上下左右とTitleContainerViewの上下左右を一致させるように制約をつけます。

これをViewControllerへ紐づけていきます。
ViewController
import UIKit
final class MoreReadViewController: UIViewController {
@IBOutlet private var heightView: UIView!
@IBAction private func moreReadButtonTapped(_ sender: UIButton) {
UIView.animate(withDuration: 0.2) { [weak self] in
guard let self = self else { return }
self.heightView.isHidden.toggle()
}
}
}
動作確認に必要なコードだけ書いています。
UIStackViewの中のパーツをhiddenにすると、そのパーツが存在しないようにレイアウトが決定されます。
TitleContainerViewの高さはもう1つのUIStackViewの中にあるUIViewの高さによって決められているので、
UIViewがhiddenになる -> 高さの制約がなくなる -> TitleContainerViewの高さはUILabelの高さによって決まる
という流れで開閉することができる、って感じだと思います。
こちらからクローンできます。
おまけ
最初に動かしたとき、こんな風なアニメーションになってしまい、かなり戸惑いました。
contentModeが何故かleftになっていたせいでした。デフォルトはtopになっているので気にする必要はないはずですが、、、





