Skip to content

Commit

Permalink
Updated to use autolayout only
Browse files Browse the repository at this point in the history
  • Loading branch information
andreamazz committed Mar 24, 2014
1 parent 34a8bab commit 6126270
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 106 deletions.
22 changes: 22 additions & 0 deletions AMScrollingNavbar/AMScrollingCollectionViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
* -----------------------------------------------------------------------------
*/

/** Scrolling init method
*
* Enables the scrolling on a generic UIView.
* Also sets the value (in points) that needs to scroll through beofre the navbar is moved back into scene
*
* @param scrollableView The UIView where the scrolling is performed.
* @param delay The delay of the downward scroll gesture
*/
- (void)followScrollView:(UIView*)scrollableView withDelay:(float)delay;

/** Scrolling init method
*
* Enables the scrolling on a generic UIView.
Expand All @@ -33,4 +43,16 @@
* Use this method when you manually change the navbar items to re-enable the fadeout
*/
- (void)refreshNavbar;

/**-----------------------------------------------------------------------------
* @name AMScrollingNavbarTableViewController Properties
* -----------------------------------------------------------------------------
*/

/** Enable or disable the scrolling
*
* Set this property to NO to disable the scrolling of the navbar.
*/
@property (nonatomic, assign) BOOL scrollingEnabled;

@end
22 changes: 22 additions & 0 deletions AMScrollingNavbar/AMScrollingNavbarTableViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
* -----------------------------------------------------------------------------
*/

/** Scrolling init method
*
* Enables the scrolling on a generic UIView.
* Also sets the value (in points) that needs to scroll through beofre the navbar is moved back into scene
*
* @param scrollableView The UIView where the scrolling is performed.
* @param delay The delay of the downward scroll gesture
*/
- (void)followScrollView:(UIView*)scrollableView withDelay:(float)delay;

/** Scrolling init method
*
* Enables the scrolling on a generic UIView.
Expand All @@ -33,4 +43,16 @@
*/
- (void)refreshNavbar;

/**-----------------------------------------------------------------------------
* @name AMScrollingNavbarTableViewController Properties
* -----------------------------------------------------------------------------
*/

/** Enable or disable the scrolling
*
* Set this property to NO to disable the scrolling of the navbar.
*/
@property (nonatomic, assign) BOOL scrollingEnabled;


@end
126 changes: 87 additions & 39 deletions AMScrollingNavbar/AMScrollingNavbarTableViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,29 @@ @interface AMScrollingNavbarTableViewController () <UIGestureRecognizerDelegate>
@property (assign, nonatomic) BOOL isExpanded;
@property (assign, nonatomic) BOOL isCompatibilityMode;
@property (assign, nonatomic) CGFloat deltaLimit;
@property (assign, nonatomic) CGFloat statusBar;
@property (assign, nonatomic) CGFloat compatibilityHeight;
@property (nonatomic, assign) float maxDelay;
@property (nonatomic, assign) float delayDistance;

@end

@implementation AMScrollingNavbarTableViewController

- (void)followScrollView:(UIView*)scrollableView
{
[self followScrollView:scrollableView withDelay:0];
}

- (void)followScrollView:(UIView*)scrollableView withDelay:(float)delay
{
self.isCompatibilityMode = ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] == NSOrderedAscending);
[self calculateConstants];

self.scrollableView = scrollableView;

self.scrollingEnabled = YES;

self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self.panGesture setMaximumNumberOfTouches:1];

Expand All @@ -46,13 +56,17 @@ - (void)followScrollView:(UIView*)scrollableView
// Use tintColor instead of barTintColor on iOS < 7
if ([self.navigationController.navigationBar respondsToSelector:@selector(setBarTintColor:)]) {
if (!self.navigationController.navigationBar.barTintColor) {
NSLog(@"[%s]: %@", __func__, @"Warning: no bar tint color set");
NSLog(@"[%s]: %@", __PRETTY_FUNCTION__, @"[AMScrollingNavbarViewController] Warning: no bar tint color set");
}
[self.overlay setBackgroundColor:self.navigationController.navigationBar.barTintColor];
} else {
[self.overlay setBackgroundColor:self.navigationController.navigationBar.tintColor];
}

if ([self.navigationController.navigationBar isTranslucent]) {
NSLog(@"[%s]: %@", __PRETTY_FUNCTION__, @"[AMScrollingNavbarViewController] Warning: the navigation bar should not be translucent");
}

[self.overlay setUserInteractionEnabled:NO];
[self.overlay setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[self.navigationController.navigationBar addSubview:self.overlay];
Expand All @@ -62,6 +76,9 @@ - (void)followScrollView:(UIView*)scrollableView
selector:@selector(didBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];

self.maxDelay = delay;
self.delayDistance = delay;
}

- (void)didBecomeActive:(id)sender
Expand Down Expand Up @@ -95,25 +112,50 @@ - (void)calculateConstants
{
// Set different values for iPad/iPhone
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
self.deltaLimit = 24;
self.compatibilityHeight = 64;
if ([[UIApplication sharedApplication] isStatusBarHidden]) {
self.deltaLimit = 44;
self.compatibilityHeight = 44;
self.statusBar = 0;
} else {
self.deltaLimit = 24;
self.compatibilityHeight = 64;
self.statusBar = 20;
}
} else {
self.deltaLimit = (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ? 24 : 12);
self.compatibilityHeight = (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ? 64 : 52);
if ([[UIApplication sharedApplication] isStatusBarHidden]) {
self.deltaLimit = (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ? 44 : 32);;
self.compatibilityHeight = (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ? 44 : 32);
self.statusBar = 0;
} else {
self.deltaLimit = (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ? 24 : 12);
self.compatibilityHeight = (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) ? 64 : 52);
self.statusBar = 20;
}
}
}

- (void)showNavbar
{
if (self.scrollableView != nil) {
if (self.isCollapsed) {
CGRect rect = self.scrollableView.frame;
CGRect rect;
if ([self.scrollableView isKindOfClass:[UIWebView class]]) {
rect = ((UIWebView*)self.scrollableView).scrollView.frame;
} else {
rect = self.scrollableView.frame;
}
rect.origin.y = 0;
self.scrollableView.frame = rect;
if ([self.scrollableView isKindOfClass:[UIWebView class]]) {
((UIWebView*)self.scrollableView).scrollView.frame = rect;
} else {
self.scrollableView.frame = rect;
}
[UIView animateWithDuration:0.2 animations:^{
self.lastContentOffset = 0;
[self scrollWithDelta:-self.compatibilityHeight];
}];
} else {
[self updateNavbarAlpha:self.compatibilityHeight];
}
}
}
Expand All @@ -125,6 +167,10 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni

- (void)handlePan:(UIPanGestureRecognizer*)gesture
{
if (self.scrollingEnabled == NO) {
return;
}

CGPoint translation = [gesture translationInView:[self.scrollableView superview]];

float delta = self.lastContentOffset - translation.y;
Expand All @@ -148,6 +194,10 @@ - (void)scrollWithDelta:(CGFloat)delta
return;
}

if (self.isExpanded) {
self.isExpanded = NO;
}

frame = self.navigationController.navigationBar.frame;

if (frame.origin.y - delta < -self.deltaLimit) {
Expand All @@ -160,6 +210,7 @@ - (void)scrollWithDelta:(CGFloat)delta
if (frame.origin.y == -self.deltaLimit) {
self.isCollapsed = YES;
self.isExpanded = NO;
self.delayDistance = self.maxDelay;
}

[self updateSizingWithDelta:delta];
Expand All @@ -170,15 +221,25 @@ - (void)scrollWithDelta:(CGFloat)delta
return;
}

if (self.isCollapsed) {
self.isCollapsed = NO;
}

self.delayDistance += delta;

if (self.delayDistance > 0) {
return;
}

frame = self.navigationController.navigationBar.frame;

if (frame.origin.y - delta > 20) {
delta = frame.origin.y - 20;
if (frame.origin.y - delta > self.statusBar) {
delta = frame.origin.y - self.statusBar;
}
frame.origin.y = MIN(20, frame.origin.y - delta);
self.navigationController.navigationBar.frame = frame;

if (frame.origin.y == 20) {
if (frame.origin.y == self.statusBar) {
self.isExpanded = YES;
self.isCollapsed = NO;
}
Expand All @@ -196,29 +257,27 @@ - (void)checkForPartialScroll
[UIView animateWithDuration:0.2 animations:^{
CGRect frame;
frame = self.navigationController.navigationBar.frame;
CGFloat delta = frame.origin.y - 20;
CGFloat delta = frame.origin.y - self.statusBar;
frame.origin.y = MIN(20, frame.origin.y - delta);
self.navigationController.navigationBar.frame = frame;

self.isExpanded = YES;
self.isCollapsed = NO;

[self updateSizingWithDelta:delta];

// This line needs tweaking
// [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, self.scrollView.contentOffset.y - delta) animated:YES];
}];
} else {
// And back up
[UIView animateWithDuration:0.2 animations:^{
CGRect frame;
frame = self.navigationController.navigationBar.frame;
CGFloat delta = frame.origin.y + 24;
CGFloat delta = frame.origin.y + self.deltaLimit;
frame.origin.y = MAX(-self.deltaLimit, frame.origin.y - delta);
self.navigationController.navigationBar.frame = frame;

self.isExpanded = NO;
self.isCollapsed = YES;
self.delayDistance = self.maxDelay;

[self updateSizingWithDelta:delta];
}];
Expand All @@ -227,7 +286,20 @@ - (void)checkForPartialScroll

- (void)updateSizingWithDelta:(CGFloat)delta
{
[self updateNavbarAlpha:delta];

// At this point the navigation bar is already been placed in the right position, it'll be the reference point for the other views'sizing
CGRect frameNav = self.navigationController.navigationBar.frame;

// Move and expand (or shrink) the superview of the given scrollview
CGRect frame = self.scrollableView.superview.frame;
frame.origin.y = frameNav.origin.y + frameNav.size.height;
frame.size.height = [UIScreen mainScreen].bounds.size.height - frame.origin.y;
self.scrollableView.superview.frame = frame;
}

- (void)updateNavbarAlpha:(CGFloat)delta
{
CGRect frame = self.navigationController.navigationBar.frame;

// Change the alpha channel of every item on the navbr. The overlay will appear, while the other objects will disappear, and vice versa
Expand All @@ -241,30 +313,6 @@ - (void)updateSizingWithDelta:(CGFloat)delta
}];
self.navigationItem.titleView.alpha = alpha;
self.navigationController.navigationBar.tintColor = [self.navigationController.navigationBar.tintColor colorWithAlphaComponent:alpha];

// Move and expand (or shrink) the superview of the given scrollview
frame = self.scrollableView.superview.frame;
frame.origin.y -= delta;
frame.size.height += delta;
self.scrollableView.superview.frame = frame;

// Changing the layer's frame avoids UIWebView's glitchiness
frame = self.scrollableView.frame;
frame.size.height = self.scrollableView.superview.frame.size.height - frame.origin.y;

// if the scrolling view is a UIWebView, we need to adjust its scrollview's frame.
if ([self.scrollableView isKindOfClass:[UIWebView class]]) {
((UIWebView*)self.scrollableView).scrollView.frame = frame;
} else {
self.scrollableView.frame = frame;
}

// Keeps the view's scroll position steady until the navbar is gone
if ([self.scrollableView isKindOfClass:[UIScrollView class]]) {
[(UIScrollView*)self.scrollableView setContentOffset:CGPointMake(((UIScrollView*)self.scrollableView).contentOffset.x, ((UIScrollView*)self.scrollableView).contentOffset.y - delta)];
} else if ([self.scrollableView isKindOfClass:[UIWebView class]]) {
[((UIWebView*)self.scrollableView).scrollView setContentOffset:CGPointMake(((UIWebView*)self.scrollableView).scrollView.contentOffset.x, ((UIWebView*)self.scrollableView).scrollView.contentOffset.y - delta)];
}
}

- (void)refreshNavbar
Expand Down
18 changes: 0 additions & 18 deletions AMScrollingNavbar/AMScrollingNavbarViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -296,24 +296,6 @@ - (void)updateSizingWithDelta:(CGFloat)delta
frame.origin.y = frameNav.origin.y + frameNav.size.height;
frame.size.height = [UIScreen mainScreen].bounds.size.height - frame.origin.y;
self.scrollableView.superview.frame = frame;

// Changing the layer's frame avoids UIWebView's glitchiness
frame = self.scrollableView.frame;
frame.size.height = self.scrollableView.superview.frame.size.height - frame.origin.y;

// if the scrolling view is a UIWebView, we need to adjust its scrollview's frame.
if ([self.scrollableView isKindOfClass:[UIWebView class]]) {
((UIWebView*)self.scrollableView).scrollView.frame = frame;
} else {
self.scrollableView.frame = frame;
}

// Keeps the view's scroll position steady until the navbar is gone
if ([self.scrollableView isKindOfClass:[UIScrollView class]]) {
[(UIScrollView*)self.scrollableView setContentOffset:CGPointMake(((UIScrollView*)self.scrollableView).contentOffset.x, ((UIScrollView*)self.scrollableView).contentOffset.y - delta)];
} else if ([self.scrollableView isKindOfClass:[UIWebView class]]) {
[((UIWebView*)self.scrollableView).scrollView setContentOffset:CGPointMake(((UIWebView*)self.scrollableView).scrollView.contentOffset.x, ((UIWebView*)self.scrollableView).scrollView.contentOffset.y - delta)];
}
}

- (void)updateNavbarAlpha:(CGFloat)delta
Expand Down
Loading

0 comments on commit 6126270

Please sign in to comment.