iOS仿微博导航栏动画(CoreGraphics)的实现方法

所属分类: 软件编程 / IOS 阅读数: 555
收藏 0 赞 0 分享

前言

昨天刚做完项目的新版本、除了尝试一些新的架构之外、功能方面并没什么特别的地方。

但是顺手搞了一些还算好玩的东西、其一就是这个导航栏的动画。

感觉还算简单易懂、分享一下(其实更多是最近攒了好多封面、不贴出来憋得人难受)。

导航栏动画.gif

思路

先介绍CA的两个方法:

基于原始状态的位移

CG_EXTERN CGAffineTransform CGAffineTransformMakeTranslation(CGFloat tx,
 CGFloat ty) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

基于原始状态的形变

CG_EXTERN CGAffineTransform CGAffineTransformScale(CGAffineTransform t,
 CGFloat sx, CGFloat sy) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

知道了这两个方法、剩下就是如何使用形变和位移以达到想要的效果了。

这里、需要分两部分来看、一部分是位移、一部分是形变
而且、如果将一整个动画以及翻页动作看成1。那么位移和形变又需要分成两部分来看:0到0.5以及0.5到1。

其实一点都不难、画个图看一眼。连一元方程都不算、完全是小学算术题~甚至连奥数都算不上。

0到0.5区间内

先看形变

在0.5时、我们需要将线条长度从left_width形变成max_width


再看位移

与此同时如果想让线条在左侧看起来并没有移动、就需要将线条的x轴一点点向右移动。这个移动的值呢?

由于形变是双向的、右侧和左侧都会变长。那么对于左侧最终将是中间时最终形变差值的一半。

具体到数值:

最左侧到中心点时x轴的位移 = 最左侧到中心点时形变的差值/2 = (max_width - left_width)/2

0.5到1区间内

依旧先看形变

和之前的形变相同


形变-0.5到1

然后来看位移

同理、如果我的长度减少了X、那么我如果想保证看起来右侧位置不会改变、考虑到形变是左右同时发生、就需要向右移动X/2。

具体到数值:

中心点到最右侧时x轴的位移 = 中心点到最右时形变的差值/2 = (max_width - right_width)/2

具体函数

以我项目里两个按钮(self.titleBtn1/self.titleBtn2)为例

if (0 <= offsetRate && offsetRate <= 0.5) {
  /*
   * 左侧与中间相互移动
   */
  
  //x轴位移 :: 中间时位移 * 偏移比例系数
  CGFloat translationOfX = _translationofX_center * offsetRate * 2;
  self.line.transform = CGAffineTransformMakeTranslation(translationOfX, 0);
  
  //x轴形变 :: 1 + (最大时相对形变) * 偏移比例系数
  CGFloat flagScale = 1 + (_flagScale_center - 1) * (offsetRate * 2);
  self.line.transform = CGAffineTransformScale(self.line.transform, flagScale, 1);
  
 }else if (0.5 < offsetRate && offsetRate <= 1) {
  /*
   * 中间与右侧相互移动
   */
  
  //x轴位移 :: 中间时位移 + 最终位移 * 偏移比例系数
  CGFloat translationOfX = _translationofX_center + _translationofX_right * (offsetRate - 0.5) * 2;
  self.line.transform = CGAffineTransformMakeTranslation(translationOfX, 0);
  
  //x轴形变 :: 最大时形变 - (最大形变 - 最终形变) * 偏移比例系数
  CGFloat flagScale = _flagScale_center - (_flagScale_center - _btn2Width/_btn1Width) * (offsetRate - 0.5) * 2;

  self.line.transform = CGAffineTransformScale(self.line.transform, flagScale, 1);
 }

其中的某些参数的意义以及取值:

{
 //整体最大宽度
 CGFloat _maxWidth;
 //位于左侧时宽度
 CGFloat _btn1Width;
 //位于右侧时宽度
 CGFloat _btn2Width;
 //从左侧移到中心时x轴位移
 CGFloat _translationofX_center;
 //从中心移到右侧时x轴位移
 //所以总位移就是_translationofX_center+_translationofX_right
 CGFloat _translationofX_right;
 //位于中心时形变
 CGFloat _flagScale_center;
}

{
 _btn1Width = self.titleBtn1.width;
 _btn2Width = self.titleBtn2.width;
 _maxWidth = self.titleBtn2.right - self.titleBtn1.left;
 _translationofX_center = (_maxWidth - _btn1Width)/2;
 _translationofX_right = (_maxWidth - _btn2Width)/2;
 _flagScale_center = _maxWidth/_btn1Width;
 self.line.frame = CGRectMake(self.titleBtn1.left, self.height, self.titleBtn1.width, 1);
}

将屏幕滑动的偏移量传递进来

#pragma mark UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
 
 CGFloat offsetX = scrollView.contentOffset.x;
 CGFloat offsetRate = offsetX/BSScreen_Width;
 

 //将偏移率传递给navView
 
 [self.navView configLingWithOffsetRate:offsetRate];
}

Demo

上面的例子的代码其实都已经列出来了、没什么再单独传Demo的必要。

但是毕竟开了个帖子、连个Demo都没有不好看。于是上午干脆封装了一个小工具出来。

但是只封装了移动的动画、并没封装按钮变色等等一系列功能。


用起来也挺简单的、只要将按钮的数组、下方横线交付、在屏幕滑动的时候把偏移量传递进去、就能自动工作了。宽度啊什么都会自己算:

@interface KTNavScrollTool : NSObject


/**
 初始化

 @param titleArr 按钮数组
 @param line 需要移动的横线
 @return 实例对象
 */
- (instancetype)initWithTitleArr:(NSArray<UIView *> *)titleArr line:(UIView *)line;


/**
 移动的函数

 @param offsetRate scrollview滚动式的偏移量的比例
 */
- (void)configLingWithOffsetRate:(CGFloat)offsetRate;
@end

GitHub有兴趣可以自取  (本地下载

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

更多精彩内容其他人还在看

iOS逆向教程之跟踪函数调用详解

这篇文章主要给大家介绍了关于iOS逆向教程之跟踪函数调用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
收藏 0 赞 0 分享

iOS App连续闪退时上报crash日志的方法详解

iOS App 有时可能遇到启动必 crash 的绝境:每次打开 App 都闪退,无法正常使用App。下面这篇文章主要给大家介绍了iOS App连续闪退时上报crash日志的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
收藏 0 赞 0 分享

如何为Xcode添加删除整行、复制整行及在下方新建一行快捷键详解

xcode是苹果公司向开发人员提供的集成开发环境,开发者们经常会使用到,下面这篇文章主要给大家介绍了关于如何为Xcode添加删除整行、复制整行及在下方新建一行快捷键的相关资料,需要的朋友可以参考下。
收藏 0 赞 0 分享

iOS指纹登录(TouchID)集成方案详解

这篇文章主要为大家详细介绍了iOS指纹登录TouchID的集成方案,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

iOS动态验证码实现代码

本文通过实例代码给大家介绍了ios动态验证码的实现方法,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下吧
收藏 0 赞 0 分享

iOS模块化开发浅析

本文给大家分析了IOS在模块发开发时候的相关注意点以及简单代码做了分享,有兴趣的朋友参考学习下。
收藏 0 赞 0 分享

iOS中封装.framework及使用的方法详解

这篇文章主要给大家介绍了关于iOS中封装.framework及使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧。
收藏 0 赞 0 分享

WKWebView、WebView和JS的交互方式详解

这篇文章主要给大家介绍了关于WKWebView、WebView和JS的交互方式,文中通过示例代码介绍的非常详细,对各位iOS开发者们具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
收藏 0 赞 0 分享

ios wkwebview离线化加载h5资源解决方案

本篇文章主要介绍了ios wkwebview离线化加载h5资源解决方案,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

iOS实现带指引线的饼状图效果(不会重叠)

饼状图对大家来说应该都不陌生,下面这篇文章主要给大家介绍了关于iOS实现带指引线的饼状图效果(不会重叠)的相关资料,文章通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
收藏 0 赞 0 分享
查看更多