【Swift4】UIScrollViewで横スクロールのページングを3分で実装する方法

2020年8月29日

UIScrollViewで横スクロール型のページングを実装する方法です。
Storyboardを使用してサクッと作成していきます。

手順
1.UIScrollViewとUIPageControlの配置
2.UIScrollViewの中身を配置
3.UIScrollViewのコンテンツサイズを指定
4.UIScrollViewのデリゲートを設定しUIPageControlと連携させる

1.UIScrollViewとUIPageControlの配置

まずプロジェクトを作成したら Main.storyboard に UIScrollView と UIPageControl を配置します。

UIScrollViewは初期ではページング設定になっていないのでページングできるようにの設定を変更します。

Paging Enabled → チェックをいれる

UIPageControlの点々は初期で白色なのでわかりやすいように現在のページを黒、その他をグレーに設定しておきましょう。

その他の色 → Tint Color
現在の色 → Current Page 

2.UIScrollViewの中身を配置

UIScrollViewとUIPageControlの配置ができたら、UIScrollViewの中身となるLabelを配置してきます。

今回はLabelを3つ用意し、全てUIScrollViewの中に配置ました。
また、スクロール時にわかりやすいよう、数字と背景の色を変えています。

ここで重要なのがUIScrollViewのサイズと3つのLabelのサイズです。

ScrollView → x = 0, y = 0, width = 375, height = 300
Label 1      → x = 0, y = 0, width = 375, height = 300
Label 2      → x = 375, y = 0, width = 375, height = 300
Label 3      → x = 750, y = 0, width = 375, height = 300 

3つのLabelのx座標を ScrollViewのwidth * n となるように設定します。

3.UIScrollViewのコンテンツサイズを指定

UIScrollViewの中身を配置したら、UIScrollViewのコンテンツサイズを指定します。

UIScrollViewをReferencing OutletsでViewControllerに紐付け「scrollView」として使用できるようにします。

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    
    // スクロールビューのコンテンツサイズを指定
    scrollView.contentSize = CGSize(width: scrollView.frame.size.width * 3,
                                    height: scrollView.frame.size.height)
}

次に、scrollView.contentSizeでコンテンツサイズを指定するプログラムを記述します。

ここで補足です、UIScrollViewには2つの領域が存在します。

UIScrollViewの表示領域 = scrollView.frame
UIScrollViewの内容領域 = scrollView.contentSize

表示領域は内容領域が見える範囲です。
内容領域はスクロールして見える領域です。

内容領域が大きければ大きいほど、たくさんスクロールできるということになります。
今回はこの 内容領域にあたる横幅 を 表示領域の横幅*3 としています。
つまり、3ページ分の内容領域にしたということになります。

以上で3つめの手順は終わりです。
この状態で既に横スクロールのページングは完成しています!
試しにビルドしてみてください。

UIScrollViewのデリゲートを設定しUIPageControlと連携させる

UIScrollViewのコンテンツサイズを指定し、横スクロールできるようになったら、最後にUIPageControlと連携させて、現在何ページ目を表示しているかわかるようにしてあげましょう。


まず最初にUIScrollViewのdelegeteをViewControllerに設定します。

class ViewController: UIViewController, UIScrollViewDelegate {
  // UIScrollViewDelegate を追加
}

プログラム側も変更します。
UIScrollViewDelegate を追加しましょう。

UIPageControlをReferencing OutletsでViewControllerに紐付け「pageControl」として使用できるようにします。

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    pageControl.currentPage = Int(scrollView.contentOffset.x / scrollView.frame.size.width)
}

最後にスクロールビューのデリゲートメソッドを用意し、その中でページコントロールの現在のページ番号を指定する計算式を記述して終わりです。

まとめ

class ViewController: UIViewController, UIScrollViewDelegate {

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var pageControl: UIPageControl!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        scrollView.contentSize = CGSize(width: scrollView.frame.size.width * 3,
                                        height: scrollView.frame.size.height)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        pageControl.currentPage = Int(scrollView.contentOffset.x / scrollView.frame.size.width)
    }
}