From 71f03b919557c5dcc85316d6c364865abcf60f30 Mon Sep 17 00:00:00 2001 From: Gian Franco Zabarino Date: Fri, 11 Dec 2015 18:13:43 -0300 Subject: [PATCH] Added delegate to latest code in the original repository. --- .../ShyControllers/TLYShyViewController.h | 1 + .../ShyControllers/TLYShyViewController.m | 11 ++ TLYShyNavBar/TLYShyNavBarManager.h | 2 +- TLYShyNavBar/TLYShyNavBarManager.m | 101 ++++++++++++------ 4 files changed, 79 insertions(+), 36 deletions(-) diff --git a/TLYShyNavBar/ShyControllers/TLYShyViewController.h b/TLYShyNavBar/ShyControllers/TLYShyViewController.h index dbc1600..2c6a2fb 100644 --- a/TLYShyNavBar/ShyControllers/TLYShyViewController.h +++ b/TLYShyNavBar/ShyControllers/TLYShyViewController.h @@ -47,6 +47,7 @@ typedef CGFloat(^TLYShyViewControllerContractionAmountBlock)(UIView *view); - (CGFloat)updateYOffset:(CGFloat)deltaY; - (CGFloat)snap:(BOOL)contract; +- (CGFloat)snap:(BOOL)contract completion:(void (^)())completion; - (CGFloat)expand; - (CGFloat)contract; diff --git a/TLYShyNavBar/ShyControllers/TLYShyViewController.m b/TLYShyNavBar/ShyControllers/TLYShyViewController.m index 0742836..19a6b62 100644 --- a/TLYShyNavBar/ShyControllers/TLYShyViewController.m +++ b/TLYShyNavBar/ShyControllers/TLYShyViewController.m @@ -188,6 +188,11 @@ } - (CGFloat)snap:(BOOL)contract +{ + return [self snap:contract completion:nil]; +} + +- (CGFloat)snap:(BOOL)contract completion:(void (^)())completion { /* "The Facebook" UX dictates that: * @@ -211,6 +216,12 @@ { deltaY = [self.subShyController expand]; } + } + completion:^(BOOL finished) + { + if (completion && finished) { + completion(); + } }]; return deltaY; diff --git a/TLYShyNavBar/TLYShyNavBarManager.h b/TLYShyNavBar/TLYShyNavBarManager.h index 767ea7b..aeea1ef 100644 --- a/TLYShyNavBar/TLYShyNavBarManager.h +++ b/TLYShyNavBar/TLYShyNavBarManager.h @@ -13,7 +13,7 @@ @protocol TLYShyNavBarManagerDelegate; -/* CLASS DESCRIPTION: +/** CLASS DESCRIPTION: * ================== * Manages the relationship between a scrollView and a view * controller. Must be instantiated and assigned the scrollView diff --git a/TLYShyNavBar/TLYShyNavBarManager.m b/TLYShyNavBar/TLYShyNavBarManager.m index 2a6710c..85211e3 100644 --- a/TLYShyNavBar/TLYShyNavBarManager.m +++ b/TLYShyNavBar/TLYShyNavBarManager.m @@ -56,17 +56,17 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage if (self) { self.delegateProxy = [[TLYDelegateProxy alloc] initWithMiddleMan:self]; - + /* Initialize defaults */ self.contracting = NO; self.previousContractionState = YES; - + self.expansionResistance = 200.f; self.contractionResistance = 0.f; - + self.fadeBehavior = TLYShyNavBarFadeSubviews; self.previousYOffset = NAN; - + /* Initialize shy controllers */ self.statusBarController = [[TLYShyStatusBarController alloc] init]; self.scrollViewController = [[TLYShyScrollViewController alloc] init]; @@ -75,10 +75,10 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage self.extensionViewContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100.f, 0.f)]; self.extensionViewContainer.backgroundColor = [UIColor clearColor]; self.extensionViewContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleBottomMargin; - + self.extensionController = [[TLYShyViewController alloc] init]; self.extensionController.view = self.extensionViewContainer; - + /* hierarchy setup */ /* StatusBar <-- navbar <-->> extension <--> scrollView */ @@ -88,7 +88,7 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage self.extensionController.parent = self.navBarController; self.extensionController.child = self.scrollViewController; self.scrollViewController.parent = self.extensionController; - + /* Notification helpers */ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) @@ -110,7 +110,7 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage { _scrollView.delegate = _delegateProxy.originalDelegate; } - + [[NSNotificationCenter defaultCenter] removeObserver:self]; [_scrollView removeObserver:self forKeyPath:@"contentSize" context:kTLYShyNavBarManagerKVOContext]; } @@ -120,47 +120,47 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage - (void)setViewController:(UIViewController *)viewController { _viewController = viewController; - + if ([viewController isKindOfClass:[UITableViewController class]] || [viewController.view isKindOfClass:[UITableViewController class]]) { NSLog(@"*** WARNING: Please consider using a UIViewController with a UITableView as a subview ***"); } - + UIView *navbar = viewController.navigationController.navigationBar; NSAssert(navbar != nil, @"Please make sure the viewController is already attached to a navigation controller."); - + viewController.extendedLayoutIncludesOpaqueBars = YES; [self.extensionViewContainer removeFromSuperview]; [self.viewController.view addSubview:self.extensionViewContainer]; - + self.navBarController.view = navbar; - + [self layoutViews]; } - (void)setScrollView:(UIScrollView *)scrollView { [_scrollView removeObserver:self forKeyPath:@"contentSize" context:kTLYShyNavBarManagerKVOContext]; - + if (_scrollView.delegate == self.delegateProxy) { _scrollView.delegate = self.delegateProxy.originalDelegate; } - + _scrollView = scrollView; self.scrollViewController.scrollView = scrollView; - + if (_scrollView.delegate != self.delegateProxy) { self.delegateProxy.originalDelegate = _scrollView.delegate; _scrollView.delegate = (id)self.delegateProxy; } - + [self cleanup]; [self layoutViews]; - + [_scrollView addObserver:self forKeyPath:@"contentSize" options:0 context:kTLYShyNavBarManagerKVOContext]; } @@ -224,7 +224,7 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage { return NO; } - + return (self.isViewControllerVisible && [self _scrollViewIsSuffecientlyLong]); } @@ -234,7 +234,7 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage { return; } - + if (!isnan(self.previousYOffset)) { // 1 - Calculate the delta @@ -246,20 +246,20 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage { deltaY = MIN(0, deltaY - (self.previousYOffset - start)); } - + /* rounding to resolve a dumb issue with the contentOffset value */ CGFloat end = floorf(self.scrollView.contentSize.height - CGRectGetHeight(self.scrollView.bounds) + self.scrollView.contentInset.bottom - 0.5f); if (self.previousYOffset > end && deltaY > 0) { deltaY = MAX(0, deltaY - self.previousYOffset + end); } - + // 3 - Update contracting variable if (fabs(deltaY) > FLT_EPSILON) { self.contracting = deltaY < 0; } - + // 4 - Check if contracting state changed, and do stuff if so if (self.contracting != self.previousContractionState) { @@ -269,7 +269,7 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage // GTH: Calculate the exact point to avoid expansion resistance // CGFloat statusBarHeight = [self.statusBarController calculateTotalHeightRecursively]; - + // 5 - Apply resistance // 5.1 - Always apply resistance when contracting if (self.contracting) @@ -284,17 +284,31 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage { CGFloat availableResistance = self.expansionResistance - self.resistanceConsumed; self.resistanceConsumed = MIN(self.expansionResistance, self.resistanceConsumed + deltaY); - + deltaY = MAX(0, deltaY - availableResistance); } - + // 6 - Update the navigation bar shyViewController self.navBarController.fadeBehavior = self.fadeBehavior; - - + + // 7 - Inform the delegate if needed + CGFloat maxNavY = CGRectGetMaxY(self.navBarController.view.frame); + CGFloat maxExtensionY = CGRectGetMaxY(self.extensionViewContainer.frame); + CGFloat visibleTop; + if (self.extensionViewContainer.hidden) { + visibleTop = maxNavY; + } else { + visibleTop = MAX(maxNavY, maxExtensionY); + } + if (visibleTop == self.statusBarController.calculateTotalHeightRecursively) { + if ([self.delegate respondsToSelector:@selector(shyNavBarManagerDidBecomeFullyContracted:)]) { + [self.delegate shyNavBarManagerDidBecomeFullyContracted:self]; + } + } + [self.navBarController updateYOffset:deltaY]; } - + self.previousYOffset = self.scrollView.contentOffset.y; } @@ -304,9 +318,26 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage { return; } - + + __weak typeof(self) weakSelf; + void (^completion)() = ^ + { + typeof(self) strongSelf = weakSelf; + if (strongSelf) { + if (strongSelf.contracting) { + if ([strongSelf.delegate respondsToSelector:@selector(shyNavBarManagerDidFinishContracting:)]) { + [strongSelf.delegate shyNavBarManagerDidFinishContracting:strongSelf]; + } + } else { + if ([strongSelf.delegate respondsToSelector:@selector(shyNavBarManagerDidFinishExpanding:)]) { + [strongSelf.delegate shyNavBarManagerDidFinishExpanding:strongSelf]; + } + } + } + }; + self.resistanceConsumed = 0; - [self.navBarController snap:self.contracting]; + [self.navBarController snap:self.contracting completion:completion]; } #pragma mark - KVO @@ -337,12 +368,12 @@ static void * const kTLYShyNavBarManagerKVOContext = (void*)&kTLYShyNavBarManage { [_extensionView removeFromSuperview]; _extensionView = view; - + CGRect bounds = view.frame; bounds.origin = CGPointZero; - + view.frame = bounds; - + self.extensionViewContainer.frame = bounds; [self.extensionViewContainer addSubview:view]; self.extensionViewContainer.userInteractionEnabled = view.userInteractionEnabled; @@ -470,7 +501,7 @@ static char shyNavBarManagerKey; shyNavBarManager = [[TLYShyNavBarManager alloc] init]; self.shyNavBarManager = shyNavBarManager; } - + return shyNavBarManager; }