- 画面幅より短い場合は、Center表示させる
- 画面幅より長い場合は、左寄せで表示し横スクロール可能である
Viewの構成
Viewの構成は、UIScrollViewの中にコンテンツ用のUIViewを入れるのみです。
private let scrollView = UIScrollView()
private let contentView = UIView()
private func setupViews() {
scrollView.addSubview(contentView)
addSubview(scrollView)
}
実際に表示させたいViewは、次のようにfunc setup(_)メソッドを使って挿入させることを想定しています。
func setup(_ view: UIView) {
contentView.addSubview(view)
view.snp.makeConstraints {
$0.edges.equalTo(contentView)
}
}
制約をセットする
scrollViewの制約は、通常通り親Viewに対して同じ大きさになるよう制約をセットします。contentViewの制約は工夫が必要で、親Viewに対して横Centerの指定とleftに対してgreaterThanOrEqualToを指定します。
この2つの制約によりCenter表示が可能になります。
private func setupConstraint() {
scrollView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
contentView.snp.makeConstraints {
$0.height.equalTo(scrollView.frameLayoutGuide)
// 横幅より小さい場合は、Center
// 横幅より大きい場合は、通常の左寄せ + スクロール
$0.top.right.bottom.equalTo(scrollView.contentLayoutGuide)
$0.left.equalTo(scrollView.contentLayoutGuide).priority(.low)
$0.left.greaterThanOrEqualTo(scrollView.contentLayoutGuide)
$0.centerX.greaterThanOrEqualToSuperview()
}
}
ScrollのContent領域が定まらないというLayoutのwarningが発生したため、次の制約を追加します。
$0.left.equalTo(scrollView.contentLayoutGuide).priority(.low)
完成形のコード
上記の全てを組み合わせると、次のようなコードになります。
final class HorizontalScrollView: UIView {
private let scrollView = UIScrollView()
private let contentView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupConstraint()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupViews()
setupConstraint()
}
private func setupViews() {
scrollView.addSubview(contentView)
addSubview(scrollView)
}
private func setupConstraint() {
scrollView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
contentView.snp.makeConstraints {
$0.height.equalTo(scrollView.frameLayoutGuide)
// aligin center when content width < frame width
// aligin left when content width > frame width
$0.top.right.bottom.equalTo(scrollView.contentLayoutGuide)
$0.left.equalTo(scrollView.contentLayoutGuide).priority(.low)
$0.left.greaterThanOrEqualTo(scrollView.contentLayoutGuide)
$0.centerX.greaterThanOrEqualToSuperview()
}
}
func setup(_ view: UIView) {
contentView.addSubview(view)
view.snp.makeConstraints {
$0.edges.equalTo(contentView)
}
}
}
