文章来源:淘论文网   发布者: 毕业设计   浏览量: 46



还可以点击去查询以下关键词:
[简单]    [设置]    [状态]    [导航]    [按钮]    [标题]    [颜色]    [超简单!!! iOS设置状态栏、导航栏按钮、标题、颜色、...]   

项目介绍:

1. 要实现以下这些效果都非常简单

2. 废话不多说,先看看实现效果

3. 下面告诉你我为什么说实现这些效果非常简单

比如说要实现蚂蚁森林的导航栏效果(有以下几个需求):

刚进入导航栏透明、两边按钮和文字都是白色、状态栏也是白色

向上滚动后导航栏背景由透明逐渐变成白色

当超过某一点后,标题变成黑色、状态栏变成黑色、两边按钮变成蓝色

实现步骤:
3.1. 实现刚进入导航栏透明、两边按钮和文字都是白色、状态栏也是白色

- (void)viewDidLoad { [super viewDidLoad]; // 设置导航栏颜色为白色 [self wr_setNavBarBarTintColor:[UIColor whiteColor]]; // 设置导航栏透明度为0 [self wr_setNavBarBackgroundAlpha:0]; }

3.2. 实现剩下两个需求

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat offsetY = scrollView.contentOffset.y; if (offsetY > NAVBAR_COLORCHANGE_POINT) { CGFloat alpha = (offsetY - NAVBAR_COLORCHANGE_POINT) / NAV_HEIGHT; // 向上滚动后导航栏背景由透明逐渐变成白色 [self wr_setNavBarBackgroundAlpha:alpha]; if (alpha > 0.5) { // 当超过某一点后,两边按钮变成蓝色 [self wr_setNavBarTintColor:[UIColor colorWithRed:0 green:0.478431 blue:1 alpha:1.0]]; // 标题变成黑色 [self wr_setNavBarTitleColor:[UIColor blackColor]]; // 状态栏变成黑色 [self wr_setStatusBarStyle:UIStatusBarStyleDefault]; } else { // 当没有超过某点,上面属性还原 [self wr_setNavBarTintColor:[UIColor whiteColor]]; [self wr_setNavBarTitleColor:[UIColor whiteColor]]; [self wr_setStatusBarStyle:UIStatusBarStyleLightContent]; } } else { [self wr_setNavBarBackgroundAlpha:0]; [self wr_setNavBarTintColor:[UIColor whiteColor]]; [self wr_setNavBarTitleColor:[UIColor whiteColor]]; [self wr_setStatusBarStyle:UIStatusBarStyleLightContent]; } }

3.3. 发现没有,改变相关属性只要一句代码就完全搞定了!!!

// 一行代码搞定导航栏颜色 [self wr_setNavBarBarTintColor:[UIColor whiteColor]]; // 一行代码搞定导航栏透明度 [self wr_setNavBarBackgroundAlpha:alpha]; // 一行代码搞定导航栏两边按钮颜色 [self wr_setNavBarTintColor:[UIColor whiteColor]]; // 一行代码搞定导航栏上标题颜色 [self wr_setNavBarTitleColor:[UIColor whiteColor]]; // 一行代码搞定状态栏是 default 还是 lightContent [self wr_setStatusBarStyle:UIStatusBarStyleLightContent];

3.4. 说了这么多,看看几句代码能否实现我们需要的效果吧

3.5. 有人可能会问:这只是在一个界面里面,开题报告,但是涉及到push、pop、右滑手势怎么办呢?
答:没关系,我已经给你处理好了,你不用写一句代码!!!那么看看效果吧

4. 好了,说了这么多接下来看看如何实现的吧

4.1 实现导航栏透明渐变就很简单了,网上一找一大堆,大部分都是通过加一层的方法来实现(在这里就是加一个view到navigationBar上)

// set navigationBar barTintColor - (void)wr_setBackgroundColor:(UIColor *)color { if (self.backgroundView == nil) { // add a image(nil color) to _UIBarBackground make it clear [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; self.backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), kWRNavBarBottom)]; // _UIBarBackground is first subView for navigationBar [self.subviews.firstObject insertSubview:self.backgroundView atIndex:0]; } self.backgroundView.backgroundColor = color; } // set _UIBarBackground alpha (_UIBarBackground subviews alpha <= _UIBarBackground alpha) - (void)wr_setBackgroundAlpha:(CGFloat)alpha { UIView *barBackgroundView = self.subviews.firstObject; barBackgroundView.alpha = alpha; }

4.2 你以为就这样结束了吗,来看看下面的问题,当由透明的导航栏右滑到不透明的导航栏看看会出现什么情况?

4.3 处理右滑返回手势问题

#p#分页标题#e#

我们都知道,导航栏是属于导航控制器的,一个导航栏不可能出现两个颜色,那么右滑突兀怎么解决呢?两个方法,一个方法是自定义导航栏(后面会说),另一个方法是改变导航栏颜色,我们假设当前控制器为fromVC,返回的控制器为toVC,如果可以实现从 fromVC 右滑到 toVC 导航栏颜色渐变那么问题就解决了!但是导航栏只有一个颜色啊~~~怎么办?
同样,可以通过加一层的方法来解决。我们可以记录一下 fromVC消失前对应的导航栏颜色 和 toVC 当前的导航栏颜色,然后根据右滑进度percentComplete,来计算渐变色,这样问题就解决了!

记录ViewController对应导航栏的颜色和透明度

// navigationBar barTintColor - (UIColor *)wr_navBarBarTintColor { UIColor *barTintColor = (UIColor *)objc_getAssociatedObject(self, &kWRNavBarBarTintColorKey); return (barTintColor != nil) ? barTintColor : [UIColor defaultNavBarBarTintColor]; } - (void)wr_setNavBarBarTintColor:(UIColor *)color { objc_setAssociatedObject(self, &kWRNavBarBarTintColorKey, color, OBJC_ASSOCIATION_RETAIN_NONATOMIC); if ([[self wr_customNavBar] isKindOfClass:[UINavigationBar class]]) { UINavigationBar *navBar = (UINavigationBar *)[self wr_customNavBar]; [navBar wr_setBackgroundColor:color]; } else { if ([self pushToCurrentVCFinished] == YES && [self pushToNextVCFinished] == NO) { [self.navigationController setNeedsNavigationBarUpdateForBarTintColor:color]; } } } // navigationBar _UIBarBackground alpha - (CGFloat)wr_navBarBackgroundAlpha { id barBackgroundAlpha = objc_getAssociatedObject(self, &kWRNavBarBackgroundAlphaKey); return (barBackgroundAlpha != nil) ? [barBackgroundAlpha floatValue] : [UIColor defaultNavBarBackgroundAlpha]; } - (void)wr_setNavBarBackgroundAlpha:(CGFloat)alpha { objc_setAssociatedObject(self, &kWRNavBarBackgroundAlphaKey, @(alpha), OBJC_ASSOCIATION_RETAIN_NONATOMIC); if ([[self wr_customNavBar] isKindOfClass:[UINavigationBar class]]) { UINavigationBar *navBar = (UINavigationBar *)[self wr_customNavBar]; [navBar wr_setBackgroundAlpha:alpha]; } else { if ([self pushToCurrentVCFinished] == YES && [self pushToNextVCFinished] == NO) { [self.navigationController setNeedsNavigationBarUpdateForBarBackgroundAlpha:alpha]; } } }

交换系统方法 _updateInteractiveTransition(监控右滑返回手势的进度)

// swizzling system method: _updateInteractiveTransition - (void)wr_updateInteractiveTransition:(CGFloat)percentComplete { UIViewController *fromVC = [self.topViewController.transitionCoordinator viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [self.topViewController.transitionCoordinator viewControllerForKey:UITransitionContextToViewControllerKey]; [self updateNavigationBarWithFromVC:fromVC toVC:toVC progress:percentComplete]; [self wr_updateInteractiveTransition:percentComplete]; }

根据 fromVC 与 toVC 的导航栏颜色 配合 返回手势进度计算渐变色

+ (UIColor *)middleColor:(UIColor *)fromColor toColor:(UIColor *)toColor percent:(CGFloat)percent { CGFloat fromRed = 0; CGFloat fromGreen = 0; CGFloat fromBlue = 0; CGFloat fromAlpha = 0; [fromColor getRed:&fromRed green:&fromGreen blue:&fromBlue alpha:&fromAlpha]; CGFloat toRed = 0; CGFloat toGreen = 0; CGFloat toBlue = 0; CGFloat toAlpha = 0; [toColor getRed:&toRed green:&toGreen blue:&toBlue alpha:&toAlpha]; CGFloat newRed = fromRed + (toRed - fromRed) * percent; CGFloat newGreen = fromGreen + (toGreen - fromGreen) * percent; CGFloat newBlue = fromBlue + (toBlue - fromBlue) * percent; CGFloat newAlpha = fromAlpha + (toAlpha - fromAlpha) * percent; return [UIColor colorWithRed:newRed green:newGreen blue:newBlue alpha:newAlpha]; }

改变导航栏颜色和透明度

- (void)updateNavigationBarWithFromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC progress:(CGFloat)progress { // change navBarBarTintColor UIColor *fromBarTintColor = [fromVC wr_navBarBarTintColor]; UIColor *toBarTintColor = [toVC wr_navBarBarTintColor]; UIColor *newBarTintColor = [UIColor middleColor:fromBarTintColor toColor:toBarTintColor percent:progress]; [self setNeedsNavigationBarUpdateForBarTintColor:newBarTintColor]; // change navBarTintColor UIColor *fromTintColor = [fromVC wr_navBarTintColor]; UIColor *toTintColor = [toVC wr_navBarTintColor]; UIColor *newTintColor = [UIColor middleColor:fromTintColor toColor:toTintColor percent:progress]; [self setNeedsNavigationBarUpdateForTintColor:newTintColor]; // change navBarTitleColor UIColor *fromTitleColor = [fromVC wr_navBarTitleColor]; UIColor *toTitleColor = [toVC wr_navBarTitleColor]; UIColor *newTitleColor = [UIColor middleColor:fromTitleColor toColor:toTitleColor percent:progress]; [self setNeedsNavigationBarUpdateForTitleColor:newTitleColor]; // change navBar _UIBarBackground alpha CGFloat fromBarBackgroundAlpha = [fromVC wr_navBarBackgroundAlpha]; CGFloat toBarBackgroundAlpha = [toVC wr_navBarBackgroundAlpha]; CGFloat newBarBackgroundAlpha = [UIColor middleAlpha:fromBarBackgroundAlpha toAlpha:toBarBackgroundAlpha percent:progress]; [self setNeedsNavigationBarUpdateForBarBackgroundAlpha:newBarBackgroundAlpha]; }

好了!来看看处理后的效果吧,是不是好多了呢~

4.5 咱们来处理右滑返回手势中断的问题吧~

#p#分页标题#e#

通过遵守UINavigationBarDelegate协议,论文,实现
optional public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool // same as push methods 方法来监听右滑返回手势中断的情况

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { __weak typeof (self) weakSelf = self; id<UIViewControllerTransitionCoordinator> coor = [self.topViewController transitionCoordinator]; if ([coor initiallyInteractive] == YES) { NSString *sysVersion = [[UIDevice currentDevice] systemVersion]; if ([sysVersion floatValue] >= 10) { [coor notifyWhenInteractionChangesUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { __strong typeof (self) pThis = weakSelf; [pThis dealInteractionChanges:context]; }]; } else { [coor notifyWhenInteractionEndsUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { __strong typeof (self) pThis = weakSelf; [pThis dealInteractionChanges:context]; }]; } return YES; } NSUInteger itemCount = self.navigationBar.items.count; NSUInteger n = self.viewControllers.count >= itemCount ? 2 : 1; UIViewController *popToVC = self.viewControllers[self.viewControllers.count - n]; [self popToViewController:popToVC animated:YES]; return YES; } // deal the gesture of return break off - (void)dealInteractionChanges:(id<UIViewControllerTransitionCoordinatorContext>)context { void (^animations) (UITransitionContextViewControllerKey) = ^(UITransitionContextViewControllerKey key){ UIColor *curColor = [[context viewControllerForKey:key] wr_navBarBarTintColor]; CGFloat curAlpha = [[context viewControllerForKey:key] wr_navBarBackgroundAlpha]; [self setNeedsNavigationBarUpdateForBarTintColor:curColor]; [self setNeedsNavigationBarUpdateForBarBackgroundAlpha:curAlpha]; }; // after that, cancel the gesture of return if ([context isCancelled] == YES) { double cancelDuration = [context transitionDuration] * [context percentComplete]; [UIView animateWithDuration:cancelDuration animations:^{ animations(UITransitionContextFromViewControllerKey); }]; } else { // after that, finish the gesture of return double finishDuration = [context transitionDuration] * (1 - [context percentComplete]); [UIView animateWithDuration:finishDuration animations:^{ animations(UITransitionContextToViewControllerKey); }]; } }

4.5 同样,push和pop也要处理一下 ~

但是push和pop我们拿不到进度怎么办呢?处理办法是,通过交换方法,自己实现给push和pop添加进度。

// MARK: swizzling push static CGFloat wrPushDuration = 0.10; static int wrPushDisplayCount = 0; - (CGFloat)wrPushProgress { CGFloat all = 60 * wrPushDuration; int current = MIN(all, wrPushDisplayCount); return current / all; } // swizzling system method: pushViewController - (void)wr_pushViewController:(UIViewController *)viewController animated:(BOOL)animated { __block CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(pushNeedDisplay)]; [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [CATransaction setCompletionBlock:^{ [displayLink invalidate]; displayLink = nil; wrPushDisplayCount = 0; [viewController setPushToCurrentVCFinished:YES]; }]; [CATransaction setAnimationDuration:wrPushDuration]; [CATransaction begin]; [self wr_pushViewController:viewController animated:animated]; [CATransaction commit]; }

计算push进度,并且根据进度更新导航栏颜色和透明度

// change navigationBar barTintColor smooth before push to current VC finished or before pop to current VC finished - (void)pushNeedDisplay { if (self.topViewController != nil && self.topViewController.transitionCoordinator != nil) { wrPushDisplayCount += 1; CGFloat pushProgress = [self wrPushProgress]; UIViewController *fromVC = [self.topViewController.transitionCoordinator viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [self.topViewController.transitionCoordinator viewControllerForKey:UITransitionContextToViewControllerKey]; [self updateNavigationBarWithFromVC:fromVC toVC:toVC progress:pushProgress]; } }

pop的设置方法也一样,具体请查看代码 WRNavigationBar_swift

4.6 以上都是改变导航栏的颜色和透明度,同样改变导航栏的按钮颜色和标题颜色,以及状态栏状态都和改变颜色一样,每个ViewController记录一下。需要改变的时候,ViewController 改变一下属性就ok了,非常方便!

那么接下来看一下其他demo的动态效果图吧~~~





5. 好了,来说说前面提过的自定义导航栏吧

5.1 至于怎么自定义导航栏我就不说了,来说说如果是自定义导航栏,那怎么才能像之前一样一句代码改变导航栏属性。

经过封装,自定义导航栏只需要多写一行代码!!!

// 自定义导航栏必须设置这个属性!!!!!!! [self wr_setCustomNavBar:self.navBar];#p#分页标题#e#

如果把这行代码放在基类控制器中,那么其他所有继承基类控制器都可以一句代码修改导航栏属性~~~
看看自定义导航栏的效果吧,是不是也很棒

6. 最后看一下移动导航栏的效果

实现代码

// 设置导航栏在垂直方向上平移多少距离 - (void)wr_setTranslationY:(CGFloat)translationY { // CGAffineTransformMakeTranslation 平移 self.transform = CGAffineTransformMakeTranslation(0, translationY); }

到这里就结束


这里还有:


还可以点击去查询:
[简单]    [设置]    [状态]    [导航]    [按钮]    [标题]    [颜色]    [超简单!!! iOS设置状态栏、导航栏按钮、标题、颜色、...]   

请扫码加微信 微信号:sj52abcd


下载地址: http://www.taolw.com/down/6712.docx
  • 上一篇:一个iOS渐变背景毕业设计动画效果的Switch
  • 下一篇:对动画的一些实际应用SGAnimation