- 画面幅より短い場合は、Center表示させる
- 画面幅より長い場合は、左寄せで表示し横スクロール可能である
Viewの構成
Viewの構成は、UIScrollViewの中にコンテンツ用のUIViewを入れるのみです。1 2 3 4 5 6 7 8 | private let scrollView = UIScrollView() private let contentView = UIView() private func setupViews() { scrollView.addSubview(contentView) addSubview(scrollView) } |
実際に表示させたいViewは、次のようにfunc setup(_)メソッドを使って挿入させることを想定しています。
1 2 3 4 5 6 | func setup(_ view: UIView) { contentView.addSubview(view) view.snp.makeConstraints { $ 0 .edges.equalTo(contentView) } } |
制約をセットする
scrollViewの制約は、通常通り親Viewに対して同じ大きさになるよう制約をセットします。contentViewの制約は工夫が必要で、親Viewに対して横Centerの指定とleftに対してgreaterThanOrEqualToを指定します。
この2つの制約によりCenter表示が可能になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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が発生したため、次の制約を追加します。
1 | $ 0 .left.equalTo(scrollView.contentLayoutGuide).priority(.low) |
完成形のコード
上記の全てを組み合わせると、次のようなコードになります。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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) } } } |