
2、彩票转盘

3、图片折叠

4、进度条旋转

5、粒子效果

一、切换图片
看起来很复杂的动画,通过少量的计算和编码就可以简单的实现。要做到这一步,必须是需要研究iOS开发中的Core Animation和Core Graphics框架的。日常工作中,对于很多东西不求甚解,只是拿过来用,甚至都不研究、封装一下别人代码,这种做法是很不好的。我喜欢自己造轮子,轮子造多了,开发经验与思维也就提升上去了。
这个动画实现是比较简单的,利用了CABasicAnimation、CAKeyframeAnimation和CAAnimationGroup。看似是两张图片各自有着自己不同的动画,实际不过是一个动画方法,其平移方向与旋转角度的不同。
我是用了CABasicAnimation设置了view的zPosition值,CAKeyframeAnimation对象设计了图片的位移与旋转动画,然后将之放到CAAnimationGroup对象里面,开始动画。
这里有一个注意点,那就是Core Animation设置的动画位移、旋转、缩放都只是一个假象,实际上的view该怎么还是怎么样,并未真正有过变化。所以,在动画结束后,想要正确的效果,那么需要设置view的zPosition值,这个值越大,view越在前面(z轴方向上的“前面”)。
代码:
#import "ViewController.h"@interface ViewController ()@property (nonatomic, strong) NSMutableArray *images;@property (nonatomic, assign) int currentIndex;@property (weak, nonatomic) IBOutlet UIImageView *currentImageView;@property (weak, nonatomic) IBOutlet UIImageView *behindImageView;@end@implementation ViewController- (NSMutableArray *)images{if (_images == nil) {_images = [NSMutableArray array];for (int i = 1; i <= 7; i++) {UIImage *image = [UIImage imageNamed: [NSString stringWithFormat:@"%d",i]];[_images addObject:image];}}return _images;}- (void)viewDidLoad{[super viewDidLoad];self.currentIndex = 0;self.currentImageView.image = self.images[_currentIndex];}- (void)addAnimateWithPoint:(CGPoint )point angle:(CGFloat)angle fromZ:(CGFloat)fromZ toZ:(CGFloat)toZ view:(UIView *)view{CABasicAnimation *zPosition = [[CABasicAnimation alloc] init];zPosition.keyPath = @"zPosition";zPosition.fromValue = @(fromZ);zPosition.toValue = @(toZ);zPosition.duration = 1.2;CAKeyframeAnimation *rotation = [[CAKeyframeAnimation alloc] init];rotation.keyPath = @"transform.rotation";rotation.values = @[@(0), @(angle), @(0)];rotation.duration = 2;rotation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];CAKeyframeAnimation *position = [[CAKeyframeAnimation alloc] init];position.keyPath = @"position";// CGPointMake(110, -20)position.values = @[[NSValue valueWithCGPoint:CGPointZero],[NSValue valueWithCGPoint:point],[NSValue valueWithCGPoint:CGPointZero]];position.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];position.additive = YES;position.duration = 1.2;CAAnimationGroup *animateGroup = [[CAAnimationGroup alloc] init];animateGroup.animations = @[zPosition, rotation, position];// animateGroup.beginTime = 0.5;animateGroup.delegate = self;animateGroup.duration = 1.2;[animateGroup setValue:view forKey:@"view"];[view.layer addAnimation:animateGroup forKey:nil]; view.layer.zPosition = toZ;}- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{CAAnimationGroup *group = [anim valueForKey:@"view"];if (group != nil) {self.currentImageView.image = self.images[_currentIndex];self.currentImageView.layer.zPosition = 1;self.behindImageView.image = nil;self.behindImageView.layer.zPosition = -1;}}- (IBAction)previous:(id)sender {self.currentIndex = (self.currentIndex + 1) % self.images.count;self.behindImageView.image = self.images[_currentIndex];[self addAnimateWithPoint:CGPointMake(-90, 20) angle:0.15 fromZ:-1 toZ:1 view:self.behindImageView];[self addAnimateWithPoint:CGPointMake(90, -20) angle:-0.15 fromZ:1 toZ:-1 view:self.currentImageView];}- (IBAction)next:(id)sender {self.currentIndex = (self.currentIndex + 6) % self.images.count;self.behindImageView.image = self.images[_currentIndex];[self addAnimateWithPoint:CGPointMake(-90, 20) angle:-0.15 fromZ:-1 toZ:1 view:self.behindImageView];[self addAnimateWithPoint:CGPointMake(90, -20) angle:0.15 fromZ:1 toZ:-1 view:self.currentImageView];}@end二、彩票转盘#import "ZYWheelView.h"#define ZYImageW 40#define ZYImageH 46@interface ZYButton : UIButton@end@implementation ZYButton/*** 重写此方法,截取button的点击**/- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{CGFloat btnW = self.bounds.size.width;CGFloat btnH = self.bounds.size.height;CGFloat x = 0;CGFloat y = btnH / 2;CGFloat w = btnW;CGFloat h = y;CGRect rect = CGRectMake(x, y, w, h);if (CGRectContainsPoint(rect, point)) {return nil;}else{return [super hitTest:point withEvent:event];}}- (CGRect)imageRectForContentRect:(CGRect)contentRect{CGFloat imageX = (contentRect.size.width - ZYImageW ) * 0.5;CGFloat imageY = 18;return CGRectMake(imageX, imageY, ZYImageW, ZYImageH);}- (void)setHighlighted:(BOOL)highlighted{ }@end@interface ZYWheelView ()@property (weak, nonatomic) IBOutlet UIImageView *wheelView;@property (nonatomic, weak) UIButton *lastSelectedBtn;@property (nonatomic, strong) CADisplayLink *timer;@end@implementation ZYWheelView+ (instancetype)wheelView{return [[[NSBundle mainBundle] loadNibNamed:@"ZYWheelView" owner:nil options:nil] lastObject];}- (void)awakeFromNib{self.wheelView.userInteractionEnabled = YES;CGFloat angle = 2 * M_PI / 12.0;UIImage *normalImage = [UIImage imageNamed:@"LuckyAstrology"];UIImage *selectedImage = [UIImage imageNamed:@"LuckyAstrologyPressed"];for (int bi = 0; bi < 12; bi++) {ZYButton *btn = [[ZYButton alloc] init];[btn setBackgroundImage:[UIImage imageNamed:@"LuckyRototeSelected"] forState:UIControlStateSelected];// 切割图片,将切割好的图片设置到按钮上// CGImage中rect是当做像素来使用// UIKit 中是点坐标系// 坐标系的特点:如果在非retain屏上 1个点等于1个像素// 在retain屏上1个点等于2个像素CGFloat imageH = ZYImageH * [UIScreen mainScreen].scale;CGFloat imageW = ZYImageW * [UIScreen mainScreen].scale;CGFloat imageY = 0;CGFloat imageX = bi * imageW;CGRect rect = CGRectMake(imageX, imageY, imageW, imageH);CGImageRef normalRef = CGImageCreateWithImageInRect(normalImage.CGImage, rect);CGImageRef selectedRef = CGImageCreateWithImageInRect(selectedImage.CGImage, rect);[btn setImage:[UIImage imageWithCGImage:normalRef] forState:UIControlStateNormal];[btn setImage:[UIImage imageWithCGImage:selectedRef] forState:UIControlStateSelected];btn.bounds = CGRectMake(0, 0, 58, 143);btn.layer.anchorPoint = CGPointMake(0.5, 1);btn.layer.position = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);btn.transform = CGAffineTransformMakeRotation(angle * bi);[btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];[self.wheelView addSubview:btn];}[self startRotating];}- (void)startRotating{if (self.timer) return;self.timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateTimer)];[self.timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];}- (void)stopRotating{[self.timer invalidate];self.timer = nil;}- (void)clickBtn:(UIButton *)btn{self.lastSelectedBtn.selected = NO;btn.selected = YES;self.lastSelectedBtn = btn;}- (IBAction)clickCenterBtn:(id)sender {self.userInteractionEnabled = NO;[self stopRotating];CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];basicAnimation.toValue = @(M_PI * 2 * 5);basicAnimation.duration = 2;basicAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];// basicAnimation.removedOnCompletion = NO;// basicAnimation.fillMode = kCAFillModeForwards;basicAnimation.delegate = self;[self.wheelView.layer addAnimation:basicAnimation forKey:nil];}- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{self.userInteractionEnabled = YES;// 根据选中的按钮获取旋转的度数,// 通过transform获取角度CGFloat angle = atan2(self.lastSelectedBtn.transform.b, self.lastSelectedBtn.transform.a);// 从实际上旋转转盘self.wheelView.transform = CGAffineTransformMakeRotation(-angle);dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{[self startRotating];}); }- (void)updateTimer{self.wheelView.transform = CGAffineTransformRotate(self.wheelView.transform, M_PI / 200);}- (void)dealloc{[self stopRotating];}@end3、图片折叠CAGradientLayer *gradientLayer = [CAGradientLayer layer];gradientLayer.frame = self.bottomView.bounds;gradientLayer.opacity = 0;gradientLayer.colors = @[(id)[UIColor clearColor].CGColor, (id)[UIColor blackColor].CGColor];self.gradientLayer = gradientLayer;[self.bottomView.layer addSublayer:gradientLayer];// 设置渐变颜色// gradientL.colors = @[(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor yellowColor].CGColor];// 设置渐变定位点// gradientL.locations = @[@0.1,@0.4,@0.5];// 设置渐变开始点,取值0~1// gradientL.startPoint = CGPointMake(0, 1);设置好之后,在pan手势的方法里面不断改变gradientLayer的opacity即可达到想要的效果。
#import "ViewController.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIImageView *topView;@property (weak, nonatomic) IBOutlet UIImageView *bottomView;@property (weak, nonatomic) IBOutlet UIView *containView;@property (nonatomic, weak) CAGradientLayer *gradientLayer;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.[self setupOtherView];//设置渐变的阴影[self setupShadow];}- (void)setupOtherView{//设置contentsRect用来表示图片显示的大小,可以做边下载边显示的UI效果,取值是(0--1)self.topView.layer.contentsRect = CGRectMake(0, 0, 1, 0.5);self.topView.layer.anchorPoint = CGPointMake(0.5, 1);self.bottomView.layer.contentsRect = CGRectMake(0, 0.5, 1, 0.5);self.bottomView.layer.anchorPoint = CGPointMake(0.5, 0);UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];[self.containView addGestureRecognizer:gesture];}- (void)setupShadow{CAGradientLayer *gradientLayer = [CAGradientLayer layer];gradientLayer.frame = self.bottomView.bounds;gradientLayer.opacity = 0;gradientLayer.colors = @[(id)[UIColor clearColor].CGColor, (id)[UIColor blackColor].CGColor];self.gradientLayer = gradientLayer;[self.bottomView.layer addSublayer:gradientLayer];// 设置渐变颜色// gradientL.colors = @[(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor yellowColor].CGColor];// 设置渐变定位点// gradientL.locations = @[@0.1,@0.4,@0.5];// 设置渐变开始点,取值0~1// gradientL.startPoint = CGPointMake(0, 1);}- (void)pan:(UIPanGestureRecognizer *)recognizer{CGFloat y = [recognizer translationInView:self.containView].y;if (y >= 300) y = 300;if (y <= -300) y = -300;// 旋转角度,往下逆时针旋转CGFloat angle = -y / 320.0 * M_PI;self.topView.layer.transform = CATransform3DIdentity;CATransform3D transfrom = CATransform3DIdentity;transfrom.m34 = -1 / 500.0;self.topView.layer.transform = CATransform3DRotate(transfrom, angle, 1, 0, 0);self.gradientLayer.opacity = y / 300.0;if (recognizer.state == UIGestureRecognizerStateEnded) {// 弹簧效果的动画// SpringWithDamping:弹性系数,越小,弹簧效果越明显[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:11 options:UIViewAnimationOptionCurveEaseInOut animations:^{self.topView.layer.transform = CATransform3DIdentity;self.gradientLayer.opacity = 0;} completion:nil];}}@end4、旋转进度条#import "ViewController.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIView *containView;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.[self setupReplicatorLayerAndAnimation];}- (void)setupReplicatorLayerAndAnimation{CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];replicatorLayer.frame = self.containView.layer.bounds;[self.containView.layer addSublayer:replicatorLayer];CALayer *layer = [CALayer layer];layer.frame = CGRectMake(self.containView.frame.size.width * 0.5, 20, 16, 16);layer.backgroundColor = [UIColor redColor].CGColor;layer.cornerRadius = layer.frame.size.width / 2;//这一句可以将初始过程移除掉layer.transform = CATransform3DMakeScale(0, 0, 0);[replicatorLayer addSublayer:layer];replicatorLayer.instanceCount = 22;CABasicAnimation *basicAn = [CABasicAnimation animationWithKeyPath:@"transform.scale"];basicAn.fromValue = @1;basicAn.toValue = @0;basicAn.duration = 1;basicAn.repeatCount = MAXFLOAT;[layer addAnimation:basicAn forKey:nil];replicatorLayer.instanceDelay = basicAn.duration / (double)replicatorLayer.instanceCount;replicatorLayer.instanceTransform = CATransform3DMakeRotation(2 * M_PI / replicatorLayer.instanceCount, 0, 0, 1);}@end5、粒子效果#import "ZYDrawView.h"@interface ZYDrawView ()@property (nonatomic, strong) UIBezierPath *bezierPath;@property (nonatomic, weak) CAReplicatorLayer *replicatorLayer;@property (nonatomic, weak) CALayer *norLayer;@endstatic int _count = 0;@implementation ZYDrawView- (UIBezierPath *)bezierPath{if (_bezierPath == nil) {_bezierPath = [[UIBezierPath alloc] init];}return _bezierPath;}- (void)awakeFromNib{CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];replicatorLayer.frame = self.bounds;[self.layer addSublayer:replicatorLayer];CALayer *layer = [CALayer layer];layer.frame = CGRectMake(0, -200, 10, 10);layer.cornerRadius = layer.frame.size.width * 0.5;layer.backgroundColor = [UIColor redColor].CGColor;[replicatorLayer addSublayer:layer];self.replicatorLayer = replicatorLayer;self.norLayer = layer;}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{CGPoint curPoint = [[touches anyObject] locationInView:self];[self.bezierPath moveToPoint:curPoint];}- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{_count++;CGPoint curPoint = [[touches anyObject] locationInView:self];[self.bezierPath addLineToPoint:curPoint];[self setNeedsDisplay];}- (void)startAnimation{CAKeyframeAnimation *keyframeAn = [CAKeyframeAnimation animationWithKeyPath:@"position"];keyframeAn.path = self.bezierPath.CGPath;keyframeAn.duration = 4;keyframeAn.repeatCount = MAXFLOAT;[self.norLayer addAnimation:keyframeAn forKey:nil];self.replicatorLayer.instanceCount = _count;self.replicatorLayer.instanceDelay = 0.1;}- (void)reDraw{_bezierPath = nil;_count = 1;[self.norLayer removeAllAnimations];[self setNeedsDisplay];}- (void)drawRect:(CGRect)rect{[self.bezierPath stroke];}@end以上内容是小编给大家介绍的Core Animation一些Demo总结 (动态切换图片、大转盘、图片折叠、进度条等动画效果),希望对大家以上帮助!