版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.09.17 |
前言
如果你细看了我前面写的有关动画的部分,就知道前面介绍了
CoreAnimation
、序列帧以及LOTAnimation
等很多动画方式,接下来几篇我们就以动画示例为线索,进行动画的讲解。部分相关代码已经上传至GitHub - 刀客传奇。感兴趣的可以看我写的前面几篇。
1. 动画示例(一) —— 一种外扩的简单动画
2. 动画示例(二) —— 一种抖动的简单动画
3. 动画示例(三) —— 仿头条一种LOTAnimation动画
4. 动画示例(四) —— QuartzCore之CAEmitterLayer下雪❄️动画
5. 动画示例(五) —— QuartzCore之CAEmitterLayer烟花动画
6. 动画示例(六) —— QuartzCore之CAEmitterLayer、CAReplicatorLayer和CAGradientLayer简单动画
7. 动画示例(七) —— 基于CAShapeLayer图像加载过程的简单动画(一)
8. 动画示例(八) —— UIViewController间转场动画的实现 (一)
9. 动画示例(九) —— 一种复杂加载动画的实现 (一)
10. 动画示例(十) —— 一种弹性动画的实现 (一)
功能需求
我们就是要实现下面这种弹性的动画:
这里要注意:
背景的白色和红色视图不是一个弹性系数进行弹性动画的。
功能实现
首先建立工程,并在sb中进行视图和约束设置如下所示:
然后我们补充代码
1. ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
2. ViewController.m
#import "ViewController.h"
#import "JJElasticView.h"
@interface ViewController ()
@property (nonatomic, strong) JJElasticView *elasticView;
@end
@implementation ViewController
#pragma mark - OVerride Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Object Private Function
- (void)initUI
{
if (self.elasticView) {
self.elasticView = nil;
}
UINib *nib = [UINib nibWithNibName:@"JJElasticView" bundle:nil];
self.elasticView = [[nib instantiateWithOwner:nil options:nil] firstObject];
[self.view addSubview:self.elasticView];
self.elasticView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
}
#pragma mark - Action && Notification
- (IBAction)startButtonDidClick:(UIButton *)sender
{
[self initUI];
}
@end
这里我们看见JJElasticView
是一个自定义View并利用xib进行的设置和约束,下面看一下xib设置。
然后我们添加代码:
#import "JJElasticView.h"
@interface JJElasticView()
@property (weak, nonatomic) IBOutlet UIView *backView;
@property (weak, nonatomic) IBOutlet UIView *startView;
@end
@implementation JJElasticView
#pragma mark - Override Base Function
- (void)awakeFromNib
{
[super awakeFromNib];
[self initUI];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if ([touches.anyObject.view isMemberOfClass:[self.backView class]]) {
return;
}
[self removeFromSuperview];
}
#pragma mark - Object Private Function
- (void)initUI
{
CGAffineTransform beginTransform = CGAffineTransformMakeTranslation(0, 200);
self.backView.transform = beginTransform;
self.startView.transform = beginTransform;
[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:10 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.startView.transform = CGAffineTransformIdentity;
self.backView.transform = CGAffineTransformIdentity;
} completion:nil];
}
@end
Build并Run,查看效果如下所示:
是不是有什么不对?是的,下面的白色背景视图和红色视图的动画节奏是一样的,导致了背景看着跟着往上面飘,这个效果不是很好。下面我们要做的就是将白色背景和红色视图分开两个动画设置,这样让白色背景看着像是不动一样,红色背景进行Spring动画,这样就有弹出去又落下来的效果了。
修改initUI
方法,如下所示:
- (void)initUI
{
CGAffineTransform beginTransform = CGAffineTransformMakeTranslation(0, 200);
self.backView.transform = beginTransform;
self.startView.transform = beginTransform;
[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:10 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.startView.transform = CGAffineTransformIdentity;
} completion:nil];
[UIView animateWithDuration:0.15 animations:^{
self.backView.transform = CGAffineTransformIdentity;
}];
}
这样我们将白色背景视图动画时间设置为0.15s,将红色视图动画设置为0.5s,这样就可以让白色背景看着不动,红色自己做弹性Spring动画。效果就不展示了,和上面功能需求展示的效果是一样的。
在自定义视图中还进行了手势的处理:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if ([touches.anyObject.view isMemberOfClass:[self.backView class]]) {
return;
}
[self removeFromSuperview];
}
点击白色背景视图以外的区域,这个视图就会从父视图上移除。点击白色区域内就没有反应。
后记
本篇主要讲述了一种基于UIView的Spring弹性动画的实现,感兴趣的给个赞或者关注~~~