滾動時自動顯示與隱藏導航條定製
// // 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