Last active
August 29, 2015 14:20
-
-
Save avnerbarr/6bf776b1567c95c2a9e8 to your computer and use it in GitHub Desktop.
Parallax table view helper
This file contains 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
// | |
// 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