Created
June 21, 2015 15:19
-
-
Save Ridwy/e515b2161520d4be717a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ScrollPageController.swift | |
// ScrollPageController | |
// | |
// Created by Chiharu Nameki on 2015/06/21. | |
// Copyright (c) 2015 Chiharu Nameki. All rights reserved. | |
// | |
import UIKit | |
class ScrollPageController: UIViewController { | |
private var pages: [UIView?] = [] // viewControllersのview, 貼り付けていない場合はnil | |
var viewControllers: [UIViewController] = [] { | |
willSet { | |
for (index, _) in enumerate(viewControllers) { | |
hideViewControllerAtIndex(index) | |
} | |
} | |
didSet { | |
pages = [] | |
for _ in viewControllers { | |
pages.append(nil) | |
} | |
selectedIndex = 0 | |
setupScrollView() | |
} | |
} | |
private(set) var selectedIndex: Int = 0 | |
var selectedViewController: UIViewController { | |
return viewControllers[selectedIndex] | |
} | |
func selectViewControllerAtIndex(index: Int) { | |
selectedIndex = index | |
scrollView.bounds = frameOfPageAtIndex(selectedIndex) | |
} | |
var scrollView: UIScrollView! { | |
return view as! UIScrollView | |
} | |
override func loadView() { | |
let scrollView = UIScrollView(frame: UIScreen.mainScreen().bounds) | |
scrollView.pagingEnabled = true | |
view = scrollView | |
} | |
override func viewWillAppear(animated: Bool) { | |
super.viewWillAppear(animated) | |
scrollView.addObserver(self, forKeyPath: "frame", options: .Initial | .New, context: nil) | |
scrollView.addObserver(self, forKeyPath: "bounds", options: .Initial | .New, context: nil) | |
} | |
override func viewDidDisappear(animated: Bool) { | |
super.viewDidDisappear(animated) | |
scrollView.removeObserver(self, forKeyPath: "frame") | |
scrollView.removeObserver(self, forKeyPath: "bounds") | |
} | |
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { | |
if keyPath == "frame" { | |
setupScrollView() | |
} else if keyPath == "bounds" { | |
layoutPages() | |
selectedIndex = Int(scrollView.bounds.midX / scrollView.bounds.size.width) | |
} | |
} | |
private func setupScrollView() { | |
let pageSize = scrollView.bounds.size | |
scrollView.contentSize.height = pageSize.height | |
scrollView.contentSize.width = pageSize.width * CGFloat(viewControllers.count) | |
scrollView.bounds = frameOfPageAtIndex(selectedIndex) | |
} | |
private func layoutPages() { | |
let pageSize = scrollView.bounds.size | |
let startIndex = Int(scrollView.bounds.minX / pageSize.width) | |
let endIndex = Int(scrollView.bounds.maxX / pageSize.width) | |
for (index, page) in enumerate(pages) { | |
if startIndex ... endIndex ~= index { | |
showViewControllerAtIndex(index) | |
} else { | |
hideViewControllerAtIndex(index) | |
} | |
} | |
} | |
private func hideViewControllerAtIndex(index: Int) { | |
if let page = pages[index] { | |
let controller = viewControllers[index] | |
controller.willMoveToParentViewController(nil) | |
controller.view.removeFromSuperview() | |
controller.removeFromParentViewController() | |
pages[index] = nil | |
} | |
} | |
private func showViewControllerAtIndex(index: Int) { | |
if let page = pages[index] { | |
page.frame = frameOfPageAtIndex(index) | |
} else { | |
let controller = viewControllers[index] | |
addChildViewController(controller) | |
controller.view.frame = frameOfPageAtIndex(index) | |
view.addSubview(controller.view) | |
controller.didMoveToParentViewController(self) | |
pages[index] = controller.view | |
} | |
} | |
private func frameOfPageAtIndex(index: Int) -> CGRect { | |
var pageFrame = scrollView.bounds | |
pageFrame.origin.x = scrollView.bounds.size.width * CGFloat(index) | |
return pageFrame | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment