diff --git a/TLYShyNavBar/ShyControllers/TLYShyViewController.h b/TLYShyNavBar/ShyControllers/TLYShyViewController.h index 2c6a2fb..4612a94 100644 --- a/TLYShyNavBar/ShyControllers/TLYShyViewController.h +++ b/TLYShyNavBar/ShyControllers/TLYShyViewController.h @@ -36,7 +36,7 @@ typedef CGFloat(^TLYShyViewControllerContractionAmountBlock)(UIView *view); @property (nonatomic, weak) id parent; @property (nonatomic, weak) TLYShyViewController *subShyController; @property (nonatomic, weak) UIView *view; - +@property (nonatomic, readonly, assign) BOOL isContracted; @property (nonatomic) TLYShyNavBarFade fadeBehavior; /* Sticky means it will always stay in expanded state @@ -47,7 +47,9 @@ typedef CGFloat(^TLYShyViewControllerContractionAmountBlock)(UIView *view); - (CGFloat)updateYOffset:(CGFloat)deltaY; - (CGFloat)snap:(BOOL)contract; -- (CGFloat)snap:(BOOL)contract completion:(void (^)())completion; + + +- (CGFloat)snap:(BOOL)contract offset:(void (^)(CGFloat deltaY))offset completion:(void (^)())completion; - (CGFloat)expand; - (CGFloat)contract; diff --git a/TLYShyNavBar/ShyControllers/TLYShyViewController.m b/TLYShyNavBar/ShyControllers/TLYShyViewController.m index 19a6b62..f5ebab4 100644 --- a/TLYShyNavBar/ShyControllers/TLYShyViewController.m +++ b/TLYShyNavBar/ShyControllers/TLYShyViewController.m @@ -14,6 +14,10 @@ @implementation TLYShyViewController (AsParent) - (CGFloat)maxYRelativeToView:(UIView *)superview { CGPoint maxEdge = CGPointMake(0, CGRectGetHeight(self.view.bounds)); + if ([self.view isKindOfClass:[UINavigationBar class]]){ + return maxEdge.y + self.view.frame.origin.y; + } + CGPoint normalizedMaxEdge = [superview convertPoint:maxEdge fromView:self.view]; return normalizedMaxEdge.y; @@ -33,16 +37,21 @@ @interface TLYShyViewController () @property (nonatomic, assign) CGFloat contractionAmountValue; @property (nonatomic, assign) CGPoint contractedCenterValue; - -@property (nonatomic, assign) BOOL contracted; -@property (nonatomic, assign) BOOL expanded; +@property (nonatomic, readwrite, assign) BOOL isContracted; @end @implementation TLYShyViewController #pragma mark - Properties - +- (id) init +{ + self = [super init]; + if (self){ + self.isContracted = YES; + } + return self; +} // convenience - (CGPoint)expandedCenterValue { @@ -150,7 +159,7 @@ - (void)offsetCenterBy:(CGPoint)deltaPoint } - (CGFloat)updateYOffset:(CGFloat)deltaY -{ +{ if (self.subShyController && deltaY < 0) { deltaY = [self.subShyController updateYOffset:deltaY]; @@ -189,10 +198,10 @@ - (CGFloat)updateYOffset:(CGFloat)deltaY - (CGFloat)snap:(BOOL)contract { - return [self snap:contract completion:nil]; + return [self snap:contract offset:nil completion:nil]; } -- (CGFloat)snap:(BOOL)contract completion:(void (^)())completion +- (CGFloat)snap:(BOOL)contract offset:(void (^)(CGFloat deltaY))offset completion:(void (^)())completion { /* "The Facebook" UX dictates that: * @@ -207,22 +216,27 @@ - (CGFloat)snap:(BOOL)contract completion:(void (^)())completion __block CGFloat deltaY; [UIView animateWithDuration:0.2 animations:^ - { - if ((contract && self.subShyController.contracted) || (!contract && !self.expanded)) - { - deltaY = [self contract]; - } - else - { - deltaY = [self.subShyController expand]; - } - } + { + if ((contract && self.subShyController.contracted) || (!contract && !self.expanded)) + { + deltaY = [self contract]; + } + else + { + deltaY = [self.subShyController expand]; + //Shift scrollView by delta like Facebook does. + if (offset && fabs(deltaY) > FLT_EPSILON) { + offset(deltaY); + } + + } + } completion:^(BOOL finished) - { - if (completion && finished) { - completion(); - } - }]; + { + if (completion && finished) { + completion(); + } + }]; return deltaY; } @@ -234,22 +248,22 @@ - (CGFloat)expand [self _onAlphaUpdate:1.f]; CGFloat amountToMove = self.expandedCenterValue.y - self.view.center.y; - - [self _updateCenter:self.expandedCenterValue]; - [self.subShyController expand]; + [self _updateCenter:self.expandedCenterValue]; + amountToMove += [self.subShyController expand]; + self.isContracted = NO; return amountToMove; } - (CGFloat)contract { CGFloat amountToMove = self.contractedCenterValue.y - self.view.center.y; - + [self _onAlphaUpdate:FLT_EPSILON]; - - [self _updateCenter:self.contractedCenterValue]; - [self.subShyController contract]; + [self _updateCenter:self.contractedCenterValue]; + amountToMove += [self.subShyController contract]; + self.isContracted = YES; return amountToMove; } diff --git a/TLYShyNavBar/TLYShyNavBarManager.m b/TLYShyNavBar/TLYShyNavBarManager.m index c18c7b9..118f39f 100644 --- a/TLYShyNavBar/TLYShyNavBarManager.m +++ b/TLYShyNavBar/TLYShyNavBarManager.m @@ -158,7 +158,7 @@ - (void)setScrollView:(UIScrollView *)scrollView _scrollView.delegate = (id)self.delegateProxy; } - [self cleanup]; + [self cleanup: YES]; [self layoutViews]; [_scrollView addObserver:self forKeyPath:@"contentSize" options:0 context:kTLYShyNavBarManagerKVOContext]; @@ -319,8 +319,8 @@ - (void)_handleScrollingEnded return; } - __weak __typeof(self) weakSelf; - void (^completion)() = ^ + __weak __typeof(self) weakSelf = self; + void (^completion)() = ^() { __typeof(self) strongSelf = weakSelf; if (strongSelf) { @@ -336,8 +336,18 @@ - (void)_handleScrollingEnded } }; + + void (^offset)(CGFloat deltaY) = ^(CGFloat deltaY) + { + __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf.scrollView setContentOffset:CGPointMake(0, strongSelf.scrollView.contentOffset.y - deltaY)]; + } + }; + + self.resistanceConsumed = 0; - [self.navBarController snap:self.contracting completion:completion]; + [self.navBarController snap:self.contracting offset:offset completion:completion]; } #pragma mark - KVO @@ -389,7 +399,7 @@ - (void)setExtensionView:(UIView *)view - (void)prepareForDisplay { - [self cleanup]; + [self cleanup: YES]; } - (void)layoutViews @@ -401,9 +411,16 @@ - (void)layoutViews } } -- (void)cleanup +- (void)cleanup:(BOOL) expand { - [self.navBarController expand]; + + CGFloat deltaY = [self.navBarController expand]; + if (expand){ + BOOL wasDisabled = self.disable; + self.disable = YES; + [self.scrollView setContentOffset:CGPointMake(0, self.scrollView.contentOffset.y - deltaY)]; + self.disable = wasDisabled; + } self.previousYOffset = NAN; } @@ -469,8 +486,9 @@ + (void)load - (void)tly_swizzledViewWillAppear:(BOOL)animated { - [[self _internalShyNavBarManager] prepareForDisplay]; - [self tly_swizzledViewWillAppear:animated]; + TLYShyNavBarManager * navBarManager = [self _internalShyNavBarManager]; + [navBarManager cleanup: navBarManager.navBarController.isContracted]; + [self tly_swizzledViewWillAppear:animated]; } - (void)tly_swizzledViewDidLayoutSubviews @@ -481,7 +499,6 @@ - (void)tly_swizzledViewDidLayoutSubviews - (void)tly_swizzledViewWillDisappear:(BOOL)animated { - [[self _internalShyNavBarManager] cleanup]; [self tly_swizzledViewWillDisappear:animated]; } diff --git a/TLYShyNavBarDemo/TLYShyNavBarDemo/Base.lproj/Main.storyboard b/TLYShyNavBarDemo/TLYShyNavBarDemo/Base.lproj/Main.storyboard index 98bd88b..76a3585 100644 --- a/TLYShyNavBarDemo/TLYShyNavBarDemo/Base.lproj/Main.storyboard +++ b/TLYShyNavBarDemo/TLYShyNavBarDemo/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -77,14 +77,14 @@ - + @@ -97,14 +97,14 @@ - + @@ -117,14 +117,14 @@ - + @@ -137,14 +137,14 @@ - + @@ -157,14 +157,14 @@ - + @@ -177,14 +177,14 @@ - + @@ -197,14 +197,14 @@ - + @@ -217,14 +217,14 @@ - + @@ -353,7 +353,7 @@ @@ -396,7 +396,7 @@ - + @@ -628,7 +628,7 @@ - +