Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
AirbnbWalkThrough
import UIKit
class AirbnbWalkThroughViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet weak var footerView: UIView!
@IBOutlet weak var pageControl: UIPageControl!
@IBOutlet weak var scrollView: UIScrollView!
private var pageCount = 3
var imageViewContainer: UIView!
var imageViewArray = [UIImageView]()
var colorArray = [UIColor]()
override func viewDidLoad() {
super.viewDidLoad()
// scrollView
scrollView.pagingEnabled = true
scrollView.contentSize = CGSizeMake(view.frame.width * CGFloat(pageCount), view.frame.size.height)
scrollView.showsHorizontalScrollIndicator = false
scrollView.showsVerticalScrollIndicator = false
scrollView.delegate = self
scrollView.backgroundColor = UIColor.clearColor() // 後ろのイメージを表示するため
// pageControl
pageControl.numberOfPages = pageCount
pageControl.currentPage = 0
// footer
colorArray.append(UIColor.redColor())
colorArray.append(UIColor.blueColor())
colorArray.append(UIColor.yellowColor())
footerView.backgroundColor = colorArray[0]
// imageViewContainer. scrollViewの後ろ側に追加
imageViewContainer = UIView(frame: CGRectMake(0, 0, view.frame.width, view.frame.width))
view.insertSubview(imageViewContainer, belowSubview: scrollView)
// imageViewContainerのアニメーションを設定
var animation = CABasicAnimation(keyPath: "transform.scale")
animation.duration = 10.0
animation.repeatCount = HUGE
animation.autoreverses = true
animation.fromValue = 1.0
animation.toValue = 1.1
imageViewContainer.layer.addAnimation(animation, forKey: "scale-layer")
// ImageViewの設定
let frame = CGRectMake(0.0, 0.0, view.frame.size.width, view.frame.size.height)
var imageView1 = UIImageView(image: UIImage(named: "image1.jpg"))
imageView1.frame = frame
imageViewArray.append(imageView1)
var imageView2 = UIImageView(image: UIImage(named: "image2.jpg"))
imageView2.frame = frame
imageViewArray.append(imageView2)
var imageView3 = UIImageView(image: UIImage(named: "image3.jpg"))
imageView3.frame = frame
imageViewArray.append(imageView3)
// 最初は1枚目だけを追加. 後のビューはスクロールに合わせて追加・削除する.
imageViewContainer.addSubview(imageViewArray[0])
}
// MARK: UIScrollViewDelegate
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
addBothSidesImageView()
}
func scrollViewDidScroll(scrollView: UIScrollView) {
let pageWidth = scrollView.frame.size.width
if Int(fmod(scrollView.contentOffset.x , pageWidth)) == 0 {
pageControl.currentPage = Int(scrollView.contentOffset.x / pageWidth)
imageViewArray[pageControl.currentPage].alpha = 1.0
removeBothSidesImageView()
} else {
// ここで画像と色の変化を実装
let currentView = imageViewArray[pageControl.currentPage]
if let index = nextIndex {
let def = pageWidth * CGFloat(pageControl.currentPage) - scrollView.contentOffset.x
let progress = CGFloat(abs(def)) / pageWidth
let nextView = imageViewArray[index]
currentView.alpha = 1 - progress
nextView.alpha = progress
let nextColor = colorArray[index]
var currentColor = colorArray[pageControl.currentPage]
var currentRGBColor = getRGB(currentColor)
var defColors = defTwoColors(currentColor, second: nextColor)
footerView.backgroundColor = UIColor(
red: currentRGBColor.red + defColors.red * progress,
green: currentRGBColor.green + defColors.green * progress,
blue: currentRGBColor.blue + defColors.blue * progress,
alpha: currentRGBColor.alpha + defColors.alpha * progress)
}
}
}
private var nextIndex: Int? {
get {
var nextIndex: Int
let currentPageX = CGFloat(pageControl.currentPage) * view.frame.width
if scrollView.contentOffset.x < currentPageX { // 右スワイプ
nextIndex = pageControl.currentPage - 1
} else {
nextIndex = pageControl.currentPage + 1
}
if nextIndex < 0 || pageCount <= nextIndex {
return nil
}
return nextIndex
}
}
// MARK: add/remove both sides image views
private func addBothSidesImageView() {
if let nextView = pageControl.currentPage + 1 < imageViewArray.count ? imageViewArray[pageControl.currentPage + 1] : nil {
nextView.alpha = 0.0
imageViewContainer.addSubview(nextView)
}
if let priviousView = 0 <= pageControl.currentPage - 1 ? imageViewArray[pageControl.currentPage - 1] : nil {
priviousView.alpha = 0.0
imageViewContainer.addSubview(priviousView)
}
}
private func removeBothSidesImageView() {
if let nextView = pageControl.currentPage + 1 < imageViewArray.count ? imageViewArray[pageControl.currentPage + 1] : nil {
nextView.alpha = 0.0
nextView.removeFromSuperview()
}
if let priviousView = 0 <= pageControl.currentPage - 1 ? imageViewArray[pageControl.currentPage - 1] : nil {
priviousView.alpha = 0.0
priviousView.removeFromSuperview()
}
}
// MARK: UIColor helper methods
private func getRGB(color: UIColor) -> (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var rgbValue = (red: CGFloat(0.0), green: CGFloat(0.0), blue: CGFloat(0.0), alpha: CGFloat(0.0))
color.getRed(&rgbValue.red, green: &rgbValue.green, blue: &rgbValue.blue, alpha: &rgbValue.alpha)
return (rgbValue.red, rgbValue.green, rgbValue.blue, rgbValue.alpha)
}
private func defTwoColors(first: UIColor, second: UIColor) -> (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var currentColor = (red: CGFloat(0.0), green: CGFloat(0.0), blue: CGFloat(0.0), alpha: CGFloat(0.0))
var nextColor = (red: CGFloat(0.0), green: CGFloat(0.0), blue: CGFloat(0.0), alpha: CGFloat(0.0))
first.getRed(&currentColor.red, green: &currentColor.green, blue: &currentColor.blue, alpha: &currentColor.alpha)
second.getRed(&nextColor.red, green: &nextColor.green, blue: &nextColor.blue, alpha: &nextColor.alpha)
return (nextColor.red - currentColor.red, nextColor.green - currentColor.green, nextColor.blue - currentColor.blue, nextColor.alpha - currentColor.alpha)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment