iOS动画案例(1) 类似于qq账号信息里的一个动画效果

受人所托,做一个类似于qq账号信息里的一个动画,感觉挺有意思,也没感觉有多难,就开始做了,结果才发现学的数学知识都还给体育老师了,研究了大半天才做出来。

先看一下动画效果:

用到的知识点:

(1)三角函数
(2)CALayer
(3)CATransaction
(4)UIBezierPath
(5)CAKeyframeAnimation
(6)CAAnimationGroup

如图,这明显是一段圆弧,那么要确定这段一段圆弧的位置,就得确定这段圆弧的圆心和圆心角。我规定圆心在手机屏幕的左顶点,也就是(0,0),圆心角为60°。别问我为什么这么确定,我也是一点点尝试的。我们先设手机屏幕的宽度为 ScreenWidth,圆弧半径为R;那么R = ScreenWidth/cos(60°);知道了这些开始画圆弧。

// 屏幕的宽度
 CGFloat width = [UIScreen mainScreen].bounds.size.width;
 // 圆半径
 float r = 2 * width / sqrt(3);
 // 画曲线
 UIColor *color = [UIColor redColor];
 [color set];
 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0) radius:r startAngle:M_PI / 2 endAngle:M_PI / 6 clockwise:NO];
 path.lineWidth = 1.0;
 path.lineCapStyle = kCGLineCapRound;
 path.lineJoinStyle = kCGLineJoinRound;
 [path stroke];

确定了圆心角和半径就要确定ABCD四个点的坐标了,分别作为四张图片的圆心。圆弧SA和圆弧DE的圆心角一样,设定为7.5°,那么弧AB、弧BC、弧CD的圆心角设定为相等,分别为(60 - 7.5 * 2)/ 3 = 15°。那么A点的坐标就等于(R * sin7.5,R * cos7.5°);B,C,D点的坐标一样用三角函数求,分别为(R * sin22.5,R * cos22.5°),(R * sin37.5,R * cos37.5°),(R * sin52.5,R * cos52.5°)。ABCD其实都是一个按钮,下面开始放按钮。

// 放图片
 for (int i = 0; i < 4; i++) {
  // 一共四个按钮 从左到右index分别为0,1,2,3
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.frame = [self getButtonFrame:i];
  button.tag = i + 1;
  [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
  [button setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%d",i + 1]] forState:UIControlStateNormal];
  // 设置按钮为圆
  button.layer.cornerRadius = 25;
  button.layer.borderColor = [UIColor greenColor].CGColor;
  button.layer.masksToBounds = YES;
  button.layer.borderWidth = 2.0f;
  [self addSubview:button];
 }
 // 根据Index确定按钮的坐标
 - (CGRect)getButtonFrame: (int) index {
 float radians = M_PI * (7.5 + 15 * index) / 180;
 CGFloat width = [UIScreen mainScreen].bounds.size.width;
 float r = 2 * width / sqrt(3);
 CGRect frame = CGRectMake(sin(radians) * r, cos(radians) * r, 50, 50);
 frame.origin.x = frame.origin.x - 25;
 frame.origin.y = frame.origin.y - 25;
 return frame;
 }

头像默认放第一个。

 self.head = [[UIImageView alloc] initWithFrame:[self getButtonFrame:0]];
 self.head.image = [UIImage imageNamed:@"myHead"];
 self.head.layer.borderColor = [UIColor greenColor].CGColor;
 self.head.layer.masksToBounds = YES;
 self.head.layer.cornerRadius = 25;
 self.head.layer.borderWidth = 2.0f;
 [self addSubview:self.head];

之后按钮点击之后,头像移动到按钮点击的地方。

// 按钮点击事件
- (void)buttonClick:(UIButton *)button {
 // 原来图片所在按钮的index
 int preIndex = [self getPreviousIndexByFrame:self.head.frame];
 int buttonIndex = (int)button.tag - 1;
 // 点击图片所在按钮 不做任何操作
 if (preIndex == buttonIndex) {
  return;
 }
 CGFloat width = [UIScreen mainScreen].bounds.size.width;
 float r = 2 * width / sqrt(3);
 //加入动画效果
 CALayer *transitionLayer = [[CALayer alloc] init];
 //显式事务默认开启动画效果,kCFBooleanTrue关闭 保证begin和commit 之间的属性修改同时进行
 transitionLayer.contents = self.head.layer.contents;
 transitionLayer.borderColor = [UIColor greenColor].CGColor;
 transitionLayer.masksToBounds = YES;
 transitionLayer.cornerRadius = 25;
 transitionLayer.borderWidth = 2.0f;
 transitionLayer.frame = self.head.frame;
 transitionLayer.backgroundColor=[UIColor blueColor].CGColor;
 [self.layer addSublayer:transitionLayer];
 self.head.hidden = YES;
 UIBezierPath *movePath;
 //路径曲线 贝塞尔曲线
 if (buttonIndex > preIndex) {
  // 向上滑 逆时针
  movePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0) radius:r startAngle:[self getAnticlockwiseByIndex:preIndex] endAngle:[self getAnticlockwiseByIndex:buttonIndex] clockwise:NO];
  [movePath moveToPoint:transitionLayer.position];
 }else {
  // 向下滑 顺时针
  movePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0) radius:r startAngle:[self getClockwiseAngleByIndex:preIndex] endAngle:[self getClockwiseAngleByIndex:buttonIndex] clockwise:YES];
  [movePath moveToPoint:transitionLayer.position];
 }
 //关键帧动画效果
 CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
 // 动画轨迹
 positionAnimation.path = movePath.CGPath;
 // 动画完成之后是否删除动画效果
 positionAnimation.removedOnCompletion = NO;
 // 设置开始的时间
 positionAnimation.beginTime = CACurrentMediaTime();
 CGFloat time = 0.7;
 if (labs(buttonIndex - preIndex) > 1) {
  time = 0.4 * labs(buttonIndex - preIndex);
 }
 //动画总时间
 positionAnimation.duration = time;
 // 动画的方式 淡入淡出
 positionAnimation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
 // 执行完之后保存最新的状态
 positionAnimation.fillMode = kCAFillModeForwards;
 // 动画完成之后,是否回到原来的地方
 positionAnimation.autoreverses= NO;
 [transitionLayer addAnimation:positionAnimation forKey:@"opacity"];
 [CATransaction setCompletionBlock:^{
  [NSThread sleepForTimeInterval:time];
  self.head.hidden = NO;
  self.head.frame = button.frame;
  [transitionLayer removeFromSuperlayer];
 }];
}
// 根据Index获得顺时针的弧度
- (float)getAnticlockwiseByIndex: (NSInteger)index {
 return M_PI * (0.5 - (7.5 + 15 * index) / 180);
}
// 根据Index获得逆时针的弧度
- (float)getClockwiseAngleByIndex: (NSInteger)index {
 index = 3 - index;
 return M_PI * (30 + 7.5 + 15 * index) / 180;
}

这个动画的难点其实是确定四个按钮的坐标以及圆弧的半径,主要是学的数学都忘的差不多了,还好重新捡起来还算不难。

以上所述是小编给大家介绍的iOS动画案例(1) 类似于qq账号信息里的一个动画效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • IOS框架Spring常用的动画效果

    Spring 作用:开发中常用的动画效果及自定义转场动画 演示 介绍 SpringView 最重要的一个类,是一个继承自UIView的控件,所有的动画属性,都是围绕着这个类的对象 demo跑起来有一个code按钮,点击这个按钮会出现已经设置的动画属性及其api,自己可以自定义设置,其对应的api这里就不赘述了(上面的gif图片也可以看到) demo里code按钮点开显示的layer对象是用SpringView创建的对象,不是我们平时说的layer animateNext(completion:

  • IOS等待时动画效果的实现

    查询时间或长或短,为了提升用户体验,目前用的比较多的手段之一就是查询等待时添加一个动态等待效果.当我们在请求网络时加载页面时有个动作效果,效果图如下: 源代码可以网上找开源项目Coding.net,上面的效果原理为两张图片组合,外面那个则为动画转动,里面的图标则是透明度的变化:主要代码如下: 1:把它封装在EaseLoadingView里面 @interface EaseLoadingView : UIView @property (strong, nonatomic) UIImageView

  • iOS 动画 —— 礼花效果实例详细

    CAEmitterLayer 提供了一个基于 Core Animation 的粒子发射系统,使用它可以实现各种各样的粒子动画效果.此处的礼花效果,就是基于 CAEmitterLayer 的. fire.gif - (void)viewDidLoad { [super viewDidLoad]; [self makeFireworksDisplay]; } - (void)makeFireworksDisplay { // 粒子发射系统 的初始化 CAEmitterLayer *fireworks

  • 仿IOS效果 带弹簧动画的ListView

    最近项目打算做一个界面,类似于dayone首页的界面效果,dayone 是一款付费应用,目前只有IOS端.作为一个资深懒惰的程序员,奉行的宗旨是绝对不重复造一个轮子.于是乎,去网上找一大堆开源项目,发现没有找到合适的,然后,只能硬着头皮自己来了.先看看效果: 效果图 其实写起来也比较简单,就是控制ListView的头部和底部的高度就可以了, 如果用RecycleView实现起来也是一样,只是RecycleView添加头和尾巴稍微麻烦一点,处理点击事件也不是很方便,所以就基于ListView去实现

  • iOS开发中常用的各种动画、页面切面效果

    今天主要用到的动画类是CALayer下的CATransition至于各种动画类中如何继承的在这也不做赘述,网上的资料是一抓一大把.好废话少说切入今天的正题. 一.封装动画方法 1.用CATransition实现动画的封装方法如下,每句代码是何意思,请看注释之. #pragma CATransition动画实现 - (void) transitionWithType:(NSString *) type WithSubtype:(NSString *) subtype ForView : (UIVi

  • iOS动画案例(1) 类似于qq账号信息里的一个动画效果

    受人所托,做一个类似于qq账号信息里的一个动画,感觉挺有意思,也没感觉有多难,就开始做了,结果才发现学的数学知识都还给体育老师了,研究了大半天才做出来. 先看一下动画效果: 用到的知识点: (1)三角函数 (2)CALayer (3)CATransaction (4)UIBezierPath (5)CAKeyframeAnimation (6)CAAnimationGroup 如图,这明显是一段圆弧,那么要确定这段一段圆弧的位置,就得确定这段圆弧的圆心和圆心角.我规定圆心在手机屏幕的左顶点,也就

  • Android开发中模仿qq列表信息滑动删除功能

    这个效果的完成主要分为两个部分 自定义view作为listview的列表项 一个view里面包括 显示头像,名字,消息内容等的contentView和滑动才能显示出来的删除,置顶的右边菜单menuView 在手指移动的时候同时改变这两个视图的位置 重写listview 判断item向左还是向右滑动 正常的滚动还是左右滑动等等 重写onTouchEvent 进行事件分发 大致思路: listview进行事件分发,判断需要滑动还是滚动等状态,如果需要滑动将事件传递给item进行滑动处理. 在item

  • Python 抓取微信公众号账号信息的方法

    搜狗微信搜索提供两种类型的关键词搜索,一种是搜索公众号文章内容,另一种是直接搜索微信公众号.通过微信公众号搜索可以获取公众号的基本信息及最近发布的10条文章,今天来抓取一下微信公众号的账号信息 爬虫 首先通过首页进入,可以按照类别抓取,通过"查看更多"可以找出页面链接规则: import requests as req import re reTypes = r'id="pc_\d*" uigs="(pc_\d*)">([\s\S]*?)&

  • Android实现保存QQ账号与密码功能(文件存储)

    目录 1.UI界面 2.构建工具类 3.编写界面交互代码 4.运行程序 大家好,我是汤姆凯特. 写在前面:今天用保存QQ账号和密码的实战演练,带大家掌握Android存储中最基本的文件存储方式 文件存储是Android中最基本的一种数据存储方式,它与Java中的文件存储类似,都是通过I/O流形式把数据直接存储到文件中,下面我们一起来看一下如何用Android实现文件存储功能吧! 1.UI界面 1)垂直线性布局为整体框架 2)头像获取 3)子线性布局编辑框和密码框 4)登录button按钮 <?x

  • IOS获取当前版本号 Bundle ID等信息的方法详解

     IOS获取当前版本号 Bundle ID等信息的方法 1:获取bundle Id信息:[[NSBundle mainBundle]bundleIdentifier]: 2:获取版本号:[[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 3:获取build号:[[[NSBundle mainBundle]infoDictionary] objectForKey:@&quo

  • IOS实现简易版的QQ下拉列表

    下面我们通过实例代码来一步步看怎么实现, 首先建立了两个模型类, 一个Friend, 一个FriendGroup类. 数据源用的本地的一个plist文件. plist文件中包含了FriendGroup的name,friends数组等属性. Friend.h 示例代码 #import <Foundation/Foundation.h> @interface Friend : NSObject @property (nonatomic, copy) NSString *name; @end Fri

  • 类似于QQ的右滑删除效果的实现方法

    原理:删除的div在窗口的外面,用户看不到,用户右滑,显示次div <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@

  • Vuejs第七篇之Vuejs过渡动画案例全面解析

    本篇资料是小编结合官方文档整理的一套更全面细致的说明,代码更多更全. 本篇资料来于官方文档: http://cn.vuejs.org/guide/transitions.html 下面看下过渡动画相关知识: ①过渡动画的定义: 简单来说,就是当模块消失.出现时,会以什么样的形式消失和出现: 如果要使用过渡动画,则在标签里加入属性: transition="过渡动画名" 例如: <div class="box" v-if="box_1" tr

  • iOS开发中TableView类似QQ分组的折叠与展开效果

    类似QQ分组的样子,实现tableView的折叠与展开.其实要做这个效果我先想到的是在tableView中再嵌套多个tableView,这个想法实现起来就有点难了. 所以还是换个思路,把tableView的HeaderView用上了.给headerView加上手势,轻松解决折叠展开的问题. 直接上代码吧. @property (nonatomic, strong) UITableView *myTableView; @property (nonatomic, strong) NSMutableA

  • jQuery实现圣诞节礼物动画案例解析

    大致介绍 下午看到了一个送圣诞礼物的小动画,正好要快到圣诞节了,就动手模仿并改进了一些小问题 原地址:jQuery实现花式轮播之圣诞节礼物传送效果 思路:动画中一共有五个礼物,他们平均分布在屏幕中,设置最外边的两个礼物旋转一定的角度并隐藏,动画开始,每个礼物向右移动一定的位置,然后再把第五个礼物添加到第一个礼物之前,这样这五个礼物就重新排列了,在写jQ时只管礼物位置的变化就行了,因为礼物的旋转和隐藏在样式中都已经设置好了,某个礼物如果成为第一个礼物就会自动隐藏旋转 如果对其中的方法不熟悉的可以参

随机推荐