【Swift】Scroll ViewとPage Controlを使ってページを移動する方法。(Swift 2.1、XCode 7.2)
Scroll ViewとPage Controlを合わせて使う
前回の記事でUIScrollView(以下、スクロールビュー)を用いて、自分より大きい部品をスクロールして見る方法について説明した。⇒「記事」
スクロールはフリック操作で行ったが、Page Control(以下、ページコントロール)を追加すれば画面タップでページを移動したり、現在のページが一目で把握できるようになる。
そこで、本記事ではスクロールビューとページコントロールを合わせて使う方法について説明する。ページコントロールの基本的な使い方は次の記事を参照されたし。⇒「記事」
まず、ページコントロールをデバイス画面に配置することろから始める。前回記事の続きからページコントロールをデバイス画面にそのまま追加すると望ましくないことになるが何だか分かるだろうか。
その通り。ページコントロールが一緒にスクロールされてしまうのだ。ページコントロールはページを移動したり、現在ページを把握するために使われるので無くなるのは困る。
一緒にスクロールされる理由は、スクロールビューの中に格納されているすべての部品がスクロール対象になるためである。なので、スクロールしたくない部品はスクロールビューの中に入れてはいけない。しかし、最初からあったViewをスクロールビューに置き換えているため、スクロールしたくない部品を置く場所がない。
そこで、Viewの中にスクロールビューとページコントロールを格納するように作り変えることにする。
まず、下図赤枠の「Scroll View」をクリックしたあとDeleteキーを押してViewController配下にあるものをまるっと削除する。続いて、Viewをデバイス画面に配置する(青矢印)。
次に、スクロールビューをデバイス画面に配置する(下図紫矢印)。黄枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Paging Enabledにチェックを入れる。
黄緑枠のPinボタンを押して吹き出しの設定画面を表示し、上下左右からの距離をすべて0にし「Add 4 Constraints」ボタンを押す。これで、スクロールビューが画面いっぱいに表示されるようになった。
次に、イメージビューをスクロールビューの中に配置する(下図黄緑矢印)。紫枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Imageに画像ファイル名(sample_item.png)を入力する。
赤枠のPinボタンを押して吹き出しの設定画面を表示し、スクロールビューとの上下左右の距離をすべて0に設定する(青枠)。WidthとHeightにチェックを入れ、Widthに960,Heightに1000を入力して「Add 6 Constraints」ボタンを押す。これで、スクロールビューより大きいイメージビューの制約を追加した。
次にページコントロールをデバイス画面に配置する(下図青矢印)。このとき、スクロールビューの中に入れてしまわないように十分注意すること。ちなみに下図黄色線の「Scroll View」と「Page Control」の階層が同じならページコントロールはスクロールビューの外にあることが分かる。
黄緑枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Tint Colorを緑、Current Pageを赤に設定する。
紫枠のPinボタンを押して吹き出しの設定画面を表示し、Viewからの左右の距離に0、下からの距離に100を入力して「Add 3 Constraints」ボタンを押す。これで、ページコントロールがページ下部に幅いっぱいで表示されるようになった。
この段階で実際にプレイしてみよう。ページコントロールがスクロールしなくなった。
現在ページを表示する
次に、ページが変わったらページコントロールの現在ページが更新されるようにしよう。
下図紫枠のアシスタントエディタボタンを押してViewController.swiftを開く。黄緑枠のスクロールビューをドラッッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示する。Connectionに「Outlet」、Nameに「testScrollView」を入力し、Connectボタンを押す。
続いて、ページコントロールをソースコードまで運んで吹き出しの設定画面を表示する(青矢印)。Connectionに「Outlet」、Nameに「testPageControl」を入力し、Connectボタンを押す。
これで、ソースコードでスクロールビューとページコントロールを操作できるようになった。
ViewController.swiftを以下のコードのように修正する。
スクロールビューのデリゲート先に自分を設定し、「スクロール停止時に呼び出されるメソッド」を追加する。このメソッドの中で「スクロールビューのX座標 ÷ スクロールビューの幅」の商を計算し、ページコントロールのページ番号に設定している。
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 |
// // ViewController.swift // import UIKit class ViewController: UIViewController, UIScrollViewDelegate { @IBOutlet weak var testPageControl: UIPageControl! @IBOutlet weak var testScrollView: UIScrollView! //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先に自分を設定 testScrollView.delegate = self } //スクロール停止時に呼び出されるメソッド func scrollViewDidEndDecelerating(scrollView: UIScrollView) { //ページコントロールに現在のページ番号を設定する。 testPageControl.currentPage = Int(testScrollView.contentOffset.x / testScrollView.frame.maxX) } } |
以下は実際のプレイ動画。ページの移動に伴って現在ページ(赤丸)も一緒に移動するようになった。
ページコントロールを使ってページを移動する
次にページコントロールのタップでページを移動できるようにしよう。
下図水色枠のアシスタントエディタボタンを押してViewController.swiftを開く。ページコントロールをドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示する。Connectionに「Action」、Nameに「tapPageControl」、Typeに「UIPageControl」、Eventに「Value Changed」を設定し、Connectボタンを押す。
これでページコントロールが押された時に呼び出されるメソッドが追加された。
ViewController.swiftを以下のように修正する。「ページコントロールのタップ時に呼び出されるメソッド」の中で、遷移先のページ番号に応じてスクロールビューのX座標を更新している。
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 |
// // ViewController.swift // import UIKit class ViewController: UIViewController, UIScrollViewDelegate { @IBOutlet weak var testPageControl: UIPageControl! @IBOutlet weak var testScrollView: UIScrollView! //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲート先に自分を設定 testScrollView.delegate = self } //ページコントロールのタップ時に呼び出されるメソッド @IBAction func tapPageControl(sender: UIPageControl) { //スクロールビューのX座標を更新する。 testScrollView.contentOffset.x = testScrollView.frame.maxX * CGFloat(sender.currentPage) } //スクロール停止時に呼び出されるメソッド func scrollViewDidEndDecelerating(scrollView: UIScrollView) { //ページコントロールに現在のページ番号を更新する。 testPageControl.currentPage = Int(testScrollView.contentOffset.x / testScrollView.frame.maxX) } } |
以下が実際のプレイ動画。