動作環境
- 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
になっているので気にする必要はないはずですが、、、