Xcode6 + SwiftにてStoryboardで設置したUIPageControlとUIScrollViewを連携させたいのですが、

```

    import UIKit
    
    class ViewController: UIViewController, UIScrollViewDelegate {
    
        //UIScrollViewの紐付け
        @IBOutlet weak var scrollView: UIScrollView!
    
        //UIPageControlの紐付け
        @IBOutlet weak var pageControl: UIPageControl!
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
    }
    
```

紐付けしか出来ず、肝心の中身ついては何も書けず……  
スライドと共にLabelとImageを表示させたいのですが  
お詳しい方がいましたら、UIPageControlとUIScrollViewの連携の仕方を教えてくださると幸いです。
CC BY-SA 3.0
2015-01-19T12:06:02.877
4849
2015-01-22T02:42:44.563
5832
question
swift xcode
UIPageControlとUIScrollViewの連携
`UIScrollView`と`UIPageControl`を連携させるためにはスクロール位置(`contentOffset`)と選択ページ(`currentPage`)を互いに同期させる必要があるため、両者のイベントを処理する必要があります。

`UIScrollView`についてはViewControllerに`UIScrollViewDelegate`の`scrollViewDidScroll`を実装します。

```

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

`UIPageControl`はtapを拾います。

```

    @IBAction func pageControlTapped(sender:AnyObject) {
        scrollView.contentOffset = CGPointMake(scrollView.frame.size.width * pageControl.currentPage, 0)
    }
    
```
CC BY-SA 3.0
2015-01-19T12:25:47.143
4850
2015-01-19T12:37:14.427
2015-01-19T12:37:14.427
5750
5750
4849
answer
まず、サンプルコードを載せます。（コメントをいただいた後で、加筆しています。Page
Controlをタップしたときの処理、スクロールビューをスクロールしたときの処理、両方に対応しました。）

```

    import UIKit
    
    class ViewController: UIViewController, UIScrollViewDelegate {
    
        @IBOutlet weak var scrollView: UIScrollView!
        @IBOutlet weak var pageControl: UIPageControl!
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    
        @IBAction func changePage(sender: UIPageControl) {
            scrollView.setContentOffset(CGPoint(x: scrollView.bounds.size.width * CGFloat(sender.currentPage), y: 0.0), animated: true)
        }
    
        func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
            var page = Int(scrollView.contentOffset.x / scrollView.bounds.size.width)
            pageControl.currentPage = page
        }
    
    }
    
```

Page
Controlは、ボタンなどと同じUIControlサブクラスです。Outletとしてでなく、Actionで「接続」します。そのとき、senderの型を、AnyObjectからUIPageControlに変えておくと、コードを書くのが楽になります（senderを型変換せずにすむ）。サンプルでは、UIPageControlのActionメソッドをchangePage()としています。  
スクロールビューをスクロールするのに、メソッドscrollRectToVisible()を使っていましたが、やはりメソッドsetContentOffset()を使ったほうがコードが短くなるので、変更しました。  
ここで注意すべきは、Swiftでは異なる型の四則演算ができないことです。CGFloat（浮動小数点数）とInt（整数）のかけ算はできませんので、一方（ここではIntのほう）をCGFloatに変換（CGFloat(value:
Int)）しています。  
Scroll
ViewのDelegateメソッドは、scrollViewDidScroll()でなく、scrollViewDidEndDecelerating()を使います。前者を使ってみるとわかりますが、Page
Controlをタップすると、点滅が起きます。これはユーザのアクションだけでなく、プログラムによるスクロールでも、Delegateが発生するためだと考えられますが、それを回避するためです。前者のメソッドは、スクロールのアニメーションの途中で動きますが、後者のメソッドは、アニメーションが完了した時点で動くという違いがあります。
CC BY-SA 3.0
2015-01-20T02:43:20.240
4878
2015-01-22T02:42:44.563
2015-01-22T02:42:44.563
7362
7362
4849
answer