- 画面幅より短い場合は、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) } } }