iOS动画案例(1) 类似于qq账号信息里的一个动画效果
发布时间 - 2026-01-10 22:43:46 点击率:次受人所托,做一个类似于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账号信息里的一个动画效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# ios动画效果
# iOS 动画 —— 礼花效果实例详细
# iOS开发中常用的各种动画、页面切面效果
# IOS框架Spring常用的动画效果
# 仿IOS效果 带弹簧动画的ListView
# IOS等待时动画效果的实现
# 分别为
# 这段
# 类似于
# 小编
# 都是
# 顺时针
# 第一个
# 也没
# 在此
# 大半天
# 给大家
# 才发现
# 做一个
# 不做
# 还算
# 就得
# 如图
# 受人
# 所述
# 就等于
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
太平洋网站制作公司,网络用语太平洋是什么意思?
如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门
WEB开发之注册页面验证码倒计时代码的实现
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
Laravel用户密码怎么加密_Laravel Hash门面使用教程
LinuxShell函数封装方法_脚本复用设计思路【教程】
Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程
JavaScript中的标签模板是什么_它如何扩展字符串功能
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法
佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
长沙企业网站制作哪家好,长沙水业集团官方网站?
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
PHP 500报错的快速解决方法
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
香港服务器租用费用高吗?如何避免常见误区?
Laravel如何生成URL和重定向?(路由助手函数)
如何解决hover在ie6中的兼容性问题
移动端脚本框架Hammer.js
制作电商网页,电商供应链怎么做?
Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程
如何实现javascript表单验证_正则表达式有哪些实用技巧
微信小程序制作网站有哪些,微信小程序需要做网站吗?
Laravel怎么实现模型属性的自动加密
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法
php 三元运算符实例详细介绍
如何快速选择适合个人网站的云服务器配置?
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
php json中文编码为null的解决办法
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
什么是javascript作用域_全局和局部作用域有什么区别?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
在线教育网站制作平台,山西立德教育官网?
Laravel怎么在Controller之外的地方验证数据
Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门
Android中AutoCompleteTextView自动提示
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
Laravel Fortify是什么,和Jetstream有什么关系
如何彻底卸载建站之星软件?
如何有效防御Web建站篡改攻击?
Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】
5种Android数据存储方式汇总
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
教你用AI润色文章,让你的文字表达更专业
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
如何生成腾讯云建站专用兑换码?

