滚动时自动显示与隐藏导航条定制
// // AMScrollingNavbarViewController.h // AMScrollingNavbar // // Created by Andrea on 08/11/13. // Copyright (c) 2013 Andrea Mazzini. All rights reserved. // #import <UIKit/UIKit.h> /*! * @name HYBScrollRenderController * @brief 在滚动视图向上滚动时,慢慢隐藏导航条或者向下滚动时,慢慢显示导航条,支持6.0以上版本系统。 * 在任何需要使用此功能的控制器类中,只要直接继承于此HYBScrollRenderController类,并在 * 创建滚动视图的时候,调用-followScrollView:方法来设置即可。 * @note 如果此类需要继承更多的特性,可直接修改继承的父类为自定义的控制器类。也可以把此类作为所有 * 类的基础父类,在继承此类的基础上,扩展所有基础属性。如HYBSuperBaseController : HYBScrollRenderController * @author huangyibiao */ @interface HYBScrollRenderController : UIViewController /*! * @brief 允许滚动的视图,支付UIScrollView、UITableView、UIWebView * @param scrollableView 可滚动的视图 */ - (void)followScrollView:(UIView *)scrollableView; @end
// // AMScrollingNavbarViewController.m // AMScrollingNavbar // // Created by Andrea on 08/11/13. // Copyright (c) 2013 Andrea Mazzini. All rights reserved. // #import "HYBScrollRenderController.h" @interface HYBScrollRenderController () <UIGestureRecognizerDelegate> @property (nonatomic, weak) UIView *scrollableView; @property (assign, nonatomic) float lastContentOffset; @property (strong, nonatomic) UIPanGestureRecognizer *panGesture; @property (strong, nonatomic) UIView *overlay; @property (assign, nonatomic) BOOL isCollapsed; @property (assign, nonatomic) BOOL isExpanded; @end @implementation HYBScrollRenderController - (void)followScrollView:(UIView *)scrollableView { self.scrollableView = scrollableView; self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; [self.panGesture setMaximumNumberOfTouches:1]; [self.panGesture setDelegate:self]; [self.scrollableView addGestureRecognizer:self.panGesture]; /* The navbar fadeout is achieved using an overlay view with the same barTintColor. this might be improved by adjusting the alpha component of every navbar child */ CGRect frame = self.navigationController.navigationBar.frame; frame.origin = CGPointZero; self.overlay = [[UIView alloc] initWithFrame:frame]; if ([self isIOS7]) { if (self.navigationController.navigationBar.barTintColor) { [self.overlay setBackgroundColor:self.navigationController.navigationBar.barTintColor]; } } [self.overlay setUserInteractionEnabled:NO]; [self.navigationController.navigationBar addSubview:self.overlay]; [self.overlay setAlpha:0]; return; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } - (void)handlePan:(UIPanGestureRecognizer*)gesture { CGPoint translation = [gesture translationInView:[self.scrollableView superview]]; float delta = self.lastContentOffset - translation.y; self.lastContentOffset = translation.y; CGRect frame; if (delta > 0) { if (self.isCollapsed) { return; } frame = self.navigationController.navigationBar.frame; if (frame.origin.y - delta < -24) { delta = frame.origin.y + 24; } frame.origin.y = MAX(-24, frame.origin.y - delta); self.navigationController.navigationBar.frame = frame; if (frame.origin.y == -24) { self.isCollapsed = YES; self.isExpanded = NO; } [self updateSizingWithDelta:delta]; // Keeps the view's scroll position steady until the navbar is gone if ([self.scrollableView isKindOfClass:[UIScrollView class]]) { UIScrollView *scrollView = (UIScrollView *)self.scrollableView; [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y - delta)]; } } if (delta < 0) { if (self.isExpanded) { return; } frame = self.navigationController.navigationBar.frame; if (frame.origin.y - delta > 20) { delta = frame.origin.y - 20; } frame.origin.y = MIN(20, frame.origin.y - delta); self.navigationController.navigationBar.frame = frame; if (frame.origin.y == 20) { self.isExpanded = YES; self.isCollapsed = NO; } [self updateSizingWithDelta:delta]; } if ([gesture state] == UIGestureRecognizerStateEnded) { self.lastContentOffset = 0; [self checkForPartialScroll]; } return; } - (void)checkForPartialScroll { CGFloat pos = self.navigationController.navigationBar.frame.origin.y; // Get back down if (pos >= -2) { [UIView animateWithDuration:0.2 animations:^{ CGRect frame; frame = self.navigationController.navigationBar.frame; CGFloat delta = frame.origin.y - 20; frame.origin.y = MIN(20, frame.origin.y - delta); self.navigationController.navigationBar.frame = frame; self.isExpanded = YES; self.isCollapsed = NO; [self updateSizingWithDelta:delta]; }]; } else { // And back up [UIView animateWithDuration:0.2 animations:^{ CGRect frame; frame = self.navigationController.navigationBar.frame; CGFloat delta = frame.origin.y + 24; frame.origin.y = MAX(-24, frame.origin.y - delta); self.navigationController.navigationBar.frame = frame; self.isExpanded = NO; self.isCollapsed = YES; [self updateSizingWithDelta:delta]; }]; } return; } - (void)updateSizingWithDelta:(CGFloat)delta { CGRect frame = self.navigationController.navigationBar.frame; float alpha = (frame.origin.y + 24) / frame.size.height; [self.overlay setAlpha:1 - alpha]; self.navigationController.navigationBar.tintColor = [self.navigationController.navigationBar.tintColor colorWithAlphaComponent:alpha]; frame = self.scrollableView.superview.frame; frame.origin.y = self.navigationController.navigationBar.frame.origin.y; frame.origin.y += self.navigationController.navigationBar.frame.size.height; // 判断是否是ios7及其以上版本 if (![self isIOS7]) { frame.origin.y = self.navigationController.navigationBar.frame.origin.y - 20; } frame.size.height = frame.size.height + delta; self.scrollableView.superview.frame = frame; // Changing the layer's frame avoids UIWebView's glitchiness frame = self.scrollableView.layer.frame; frame.size.height += delta; self.scrollableView.layer.frame = frame; return; } - (BOOL)isIOS7 { return ([UIDevice currentDevice].systemVersion.integerValue >= 7) ? YES : NO; } @end
最后更新:2017-04-03 05:39:53