Skip to content

Instantly share code, notes, and snippets.

@avnerbarr
Last active August 29, 2015 14:20
Show Gist options
  • Save avnerbarr/6bf776b1567c95c2a9e8 to your computer and use it in GitHub Desktop.
Save avnerbarr/6bf776b1567c95c2a9e8 to your computer and use it in GitHub Desktop.
Parallax table view helper
//
// ParallaxController.swift
// ParallaxTableVIew
//
// Created by Avner on 5/2/15.
// Copyright (c) 2015 Avner. All rights reserved.
//
import UIKit
@objc protocol ParallaxControllerDelegate {
/**
Percent of parallax view under only the nav bar
:param: controller the controller
:param: intersectNavBarPercent The percent under - calculated by (max Y point of parallax) - height of nav bar iff max Y < navbar height
*/
optional func parallaxController(controller : ParallaxController,intersectNavBarPercent : CGFloat)
}
class ParallaxController: NSObject {
weak var tableView : UITableView?
weak var parallaxView : UIView?
weak var viewController : UIViewController?
weak var delegate : ParallaxControllerDelegate?
var navigationBarHeight : CGFloat?
var parallaxHeight : CGFloat?
var view : UIView? {
get {
return viewController?.view
}
}
init(parentViewController : UIViewController, tableView : UITableView,parallaxView : UIView,parallaxHeight : CGFloat, navigationBarHeight : CGFloat) {
super.init()
self.viewController = parentViewController
self.tableView = tableView
self.parallaxView = parallaxView
self.parallaxHeight = parallaxHeight
self.navigationBarHeight = navigationBarHeight
self.tableView?.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.New, context: nil)
}
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
if let tableView = self.tableView, parallaxHeight = self.parallaxHeight, navigationBarHeight = self.navigationBarHeight, parallaxView = self.parallaxView , view = self.view {
if tableView.contentOffset.y > 0 {
var newOriginY = ceil(max(navigationBarHeight + parallaxHeight - tableView.contentOffset.y, navigationBarHeight))
tableView.frame = CGRectMake(0, newOriginY, view.bounds.size.width, view.bounds.size.height - newOriginY)
parallaxView.frame = CGRectMake(0, floor(newOriginY - parallaxView.frame.height)-1, parallaxView.frame.width, parallaxView.frame.height)
} else {
parallaxView.frame = CGRectMake(0, 0, parallaxView.frame.width, tableView.frame.origin.y + ceil(abs(tableView.contentOffset.y)))
}
// pixel fraction fix
if parallaxView.frame.origin.y > 0 {
parallaxView.frame.origin.y = 0
}
// get an indication of how much of the parallax is under only the nav bar
var virtOriginY = CGRectGetMaxY(parallaxView.keyWindowFrame!) - navigationBarHeight
if virtOriginY < navigationBarHeight {
var percent = (navigationBarHeight - virtOriginY)/navigationBarHeight
self.delegate?.parallaxController?(self, intersectNavBarPercent: percent)
} else {
self.delegate?.parallaxController?(self, intersectNavBarPercent: 0)
}
}
}
deinit {
self.tableView?.removeObserver(self, forKeyPath: "contentOffset")
}
}
extension UIView {
var keyWindowFrame : CGRect? {
get {
return UIApplication.sharedApplication().keyWindow?.convertRect(self.frame, fromView: self.superview)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment