滑动UIScrollView隐藏显示导航条与标签条

Posted Jk_Chan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了滑动UIScrollView隐藏显示导航条与标签条相关的知识,希望对你有一定的参考价值。

//计算scrollview偏移量:
typedef NS_ENUM(NSInteger, ScrollDirection) {
ScrollDirectionNone,
ScrollDirectionUp,
ScrollDirectionDown,
};
ScrollDirection detectScrollDirection(currentOffsetY, previousOffsetY)
{
return currentOffsetY > previousOffsetY ? ScrollDirectionUp :
currentOffsetY < previousOffsetY ? ScrollDirectionDown :
ScrollDirectionNone;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat currentOffsetY = scrollView.contentOffset.y;
ScrollDirection currentScrollDirection = detectScrollDirection(currentOffsetY, _previousOffsetY);
CGFloat topBoundary = -scrollView.contentInset.top;
CGFloat bottomBoundary = scrollView.contentSize.height + scrollView.contentInset.bottom;

BOOL isOverTopBoundary = currentOffsetY <= topBoundary;
BOOL isOverBottomBoundary = currentOffsetY >= bottomBoundary;
BOOL isBouncing = (isOverTopBoundary && currentScrollDirection != ScrollDirectionDown) || (isOverBottomBoundary && currentScrollDirection != ScrollDirectionUp);
if (isBouncing || !scrollView.isDragging) {
return;
}
CGFloat deltaY = _previousOffsetY - currentOffsetY;
_accumulatedY += deltaY;
switch (currentScrollDirection) {
case ScrollDirectionUp:
{
BOOL isOverThreshold = _accumulatedY < -_upThresholdY;
if (isOverThreshold || isOverBottomBoundary) {
//move up deltaY
}
}
break;
case ScrollDirectionDown:
{
BOOL isOverThreshold = _accumulatedY > _downThresholdY;
if (isOverThreshold || isOverTopBoundary) {
//move down deltaY
}
}
break;
case ScrollDirectionNone:
break;
}
// reset
if (!isOverTopBoundary && !isOverBottomBoundary && _previousScrollDirection != currentScrollDirection) {
_accumulatedY = 0;
}
_previousScrollDirection = currentScrollDirection;
_previousOffsetY = currentOffsetY;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
CGFloat currentOffsetY = scrollView.contentOffset.y;
CGFloat topBoundary = -scrollView.contentInset.top;
CGFloat bottomBoundary = scrollView.contentSize.height + scrollView.contentInset.bottom;
switch (_previousScrollDirection) {
case ScrollDirectionUp:
{
BOOL isOverThreshold = _accumulatedY < -_upThresholdY;
BOOL isOverBottomBoundary = currentOffsetY >= bottomBoundary;
if (isOverThreshold || isOverBottomBoundary) {
//end move up
}
break;
}
case ScrollDirectionDown:
{
BOOL isOverThreshold = _accumulatedY > _downThresholdY;
BOOL isOverTopBoundary = currentOffsetY <= topBoundary;
if (isOverThreshold || isOverTopBoundary) {
//end dowm
}
break;
}
case ScrollDirectionNone:
break;
}
}

 

//isComplete是否完全设置显示隐藏,不是的话根据Y坐标移动量移动NavigtionBar并设置NavigationTitle颜色透明值:
- (void)moveNavigtionBar:(CGFloat)deltaY isComplete:(BOOL)isComplete isSetHide:(BOOL)isSetHide
{
void(^setNavigationBarFrameOriginY)(CGFloat originY)=^(CGFloat originY){
CGRect currentNavigationBarFrame = self.navigationController.navigationBar.frame;//当前导航栏的frame
CGSize statuBarFrameSize = [UIApplication sharedApplication].statusBarFrame.size;//状态栏大小
CGFloat statusBarHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? statuBarFrameSize.height : statuBarFrameSize.width;//判断设备旋转方向计算状态栏的高
CGFloat navigationBarHeight = currentNavigationBarFrame.size.height;//当前导航栏高度
CGFloat topLimit = -navigationBarHeight + statusBarHeight;//导航栏的高度除了状态栏的高度外还剩多少
CGFloat bottomLimit = statusBarHeight;
currentNavigationBarFrame.origin.y = fmin(fmax(originY, topLimit), bottomLimit);
CGFloat alpha = 1 - (statusBarHeight - currentNavigationBarFrame.origin.y) / statusBarHeight;//计算透明度
UIColor *titleTextColor = [UIColor colorWithWhite:0.0 alpha:alpha]; // 计算title颜色需要的隐藏度
[UIView animateWithDuration:0.1 animations:^{//动画效果
self.navigationController.navigationBar.frame = currentNavigationBarFrame;//把移动后最终的frame赋给navigationBar(改变navigationBar的frame值)
[self.navigationController.navigationBar setTitleTextAttributes:@{ NSForegroundColorAttributeName : titleTextColor }];//把计算出来的颜色值赋给navigationBar的title
UIColor *tintColor = self.navigationController.navigationBar.tintColor;
if (tintColor) {
CGFloat *components = (CGFloat *)CGColorGetComponents(tintColor.CGColor);
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:components[0] green:components[1] blue:components[2] alpha:alpha];
}
}];
};

if(!isComplete){//不是完全设置隐藏或显示,根据移动上下设置坐标
CGRect currentNavigationBarFrame = self.navigationController.navigationBar.frame;//当前导航栏的frame
CGFloat nextY = currentNavigationBarFrame.origin.y + deltaY;//计算移动后导航栏的frameY
setNavigationBarFrameOriginY(nextY);
}else{
if (isSetHide) {
CGSize statuBarFrameSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? statuBarFrameSize.height : statuBarFrameSize.width;
CGFloat navigationBarHeight = self.navigationController.navigationBar.frame.size.height;
CGFloat top = -navigationBarHeight + statusBarHeight;
setNavigationBarFrameOriginY(top);
}else{
CGSize statuBarFrameSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? statuBarFrameSize.height : statuBarFrameSize.width;
setNavigationBarFrameOriginY(statusBarHeight);
}
}
}

//isComplete是否完全设置显示隐藏,不是的话根据Y坐标移动量移动toolbar:
- (void)moveToolbar:(CGFloat)deltaY isComplete:(BOOL)isComplete isSetHide:(BOOL)isSetHide
{
void(^setToolbarOriginY)(CGFloat originY)=^(CGFloat originY){
CGRect currentToolBarFrame = self.navigationController.toolbar.frame;
CGFloat toolBarHeight = currentToolBarFrame.size.height;
CGSize viewSize = self.navigationController.view.frame.size;
CGFloat viewHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? viewSize.height : viewSize.width;
CGFloat topLimit = viewHeight - toolBarHeight;
CGFloat bottomLimit = viewHeight;
currentToolBarFrame.origin.y = fmin(fmax(originY, topLimit), bottomLimit);
[UIView animateWithDuration:0.1 animations:^{
self.navigationController.toolbar.frame = currentToolBarFrame;
}];
};

if (!isComplete) {
CGRect currentToolBarFrame = self.navigationController.toolbar.frame;
CGFloat nextY = currentToolBarFrame.origin.y + deltaY;
setToolbarOriginY(nextY);
}else{
if (isSetHide) {
CGSize viewSize = self.navigationController.view.frame.size;
CGFloat viewHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? viewSize.height : viewSize.width;
setToolbarOriginY(viewHeight);
}else{
CGSize viewSize = self.navigationController.view.frame.size;
CGFloat viewHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? viewSize.height : viewSize.width;
CGFloat toolbarHeight = self.navigationController.toolbar.frame.size.height;
setToolbarOriginY(viewHeight - toolbarHeight);
}
}
}

- (void)moveTabBar:(CGFloat)deltaY isComplete:(BOOL)isComplete isSetHide:(BOOL)isSetHide
{
void(^setTabBarOriginY)(CGFloat originY)=^(CGFloat originY){
CGRect frame = self.tabBarController.tabBar.frame;
CGFloat toolBarHeight = frame.size.height;
CGSize viewSize = self.tabBarController.view.frame.size;
CGFloat viewHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? viewSize.height : viewSize.width;
CGFloat topLimit = viewHeight - toolBarHeight;
CGFloat bottomLimit = viewHeight;
frame.origin.y = fmin(fmax(originY, topLimit), bottomLimit);
[UIView animateWithDuration:0.1 animations:^{
self.tabBarController.tabBar.frame = frame;
}];
};
if (!isComplete) {
CGRect frame = self.tabBarController.tabBar.frame;
CGFloat nextY = frame.origin.y + deltaY;
setTabBarOriginY(nextY);
}else{
if (isSetHide) {
CGSize viewSize = self.tabBarController.view.frame.size;
CGFloat viewHeight = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? viewSize.height : viewSize.width;
setTabBarOriginY(viewHeight);
}else{
CGFloat viewHeight = self.tabBarController.view.frame.size.height;
CGFloat toolbarHeight = self.tabBarController.tabBar.frame.size.height;
setTabBarOriginY(viewHeight - toolbarHeight);
}
}
}

以上是关于滑动UIScrollView隐藏显示导航条与标签条的主要内容,如果未能解决你的问题,请参考以下文章

iOS 上滑隐藏导航,下滑显示导航,仿斗鱼导航效果

微信h5滑动隐藏底部导航栏

iOS 滑动隐藏导航栏-三种方式

往下滚动,导航栏隐藏

当滚动条与jQuery一起移动时如何隐藏Div?

UISwipeGestureRecognizer 和 UIScrollView