最近在写项目集成即时通讯,音视频修改成类似QQ中收起的动画效果:
动画代码比较简单,效果:
动画View添加到window中为了方便可以不管到什么控制器都可以悬浮展示,
根据demo大致写了下代码:
//
// ShowContentView.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ShowContentView : UIView<CAAnimationDelegate>
@property (nonatomic, strong)UIView *headView;
@property (nonatomic, strong)UIButton *clicBtn;
/** 动画用的layer */
@property (strong, nonatomic)CAShapeLayer *shapeLayer;
@property (nonatomic, strong)UIButton *smallBtn;
@end
//
// ShowContentView.m
#import "ShowContentView.h"
@implementation ShowContentView
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
UIView *headView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 120, 120)];
headView.center = CGPointMake(self.center.x, 130);
[headView setBackgroundColor:[UIColor redColor]];
headView.layer.cornerRadius = 60;
headView.clipsToBounds = YES;
self.clipsToBounds = YES;
self.headView = headView;
[self addSubview:headView];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(30, [UIScreen mainScreen].bounds.size.height-80, [UIScreen mainScreen].bounds.size.width - 60, 30);
[btn setBackgroundColor:[UIColor redColor]];
[btn setTitle:@"点我" forState:UIControlStateNormal];
self.clicBtn = btn;
[btn addTarget:self action:@selector(btnclickAction:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
}
return self;
}
- (void)btnclickAction:(UIButton *)btn
{
//开始的圆形
UIBezierPath *endPath = [UIBezierPath bezierPathWithOvalInRect:self.headView.frame];
CGSize startSize = CGSizeMake(self.frame.size.width * 0.5, self.frame.size.height-self.headView.center.y);
CGFloat radius = sqrt(startSize.width*startSize.width+startSize.height*startSize.height);
CGRect statF = CGRectInset(self.headView.frame, -radius, -radius);
UIBezierPath *startPath = [UIBezierPath bezierPathWithOvalInRect:statF];
CAShapeLayer *shapLayer = [CAShapeLayer layer];
shapLayer.path = endPath.CGPath;
self.layer.mask = shapLayer;
self.shapeLayer = shapLayer;
//动画
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (id)startPath.CGPath;
pathAnimation.toValue = (id)endPath.CGPath;
pathAnimation.duration = 0.5;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.delegate = self;
pathAnimation.removedOnCompletion = NO;
pathAnimation.fillMode = kCAFillModeForwards;
[shapLayer addAnimation:pathAnimation forKey:@"shapAnmination"];
}
#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if ([anim isEqual:[self.shapeLayer animationForKey:@"shapAnmination"]]) {
CGRect rect = self.frame;
rect.origin = self.headView.frame.origin;
self.bounds = rect;
rect.size = self.headView.frame.size;
self.frame = rect;
[UIView animateWithDuration:1.0 animations:^{
self.center = CGPointMake([UIScreen mainScreen].bounds.size.width - 60, [UIScreen mainScreen].bounds.size.height - 80);
self.transform = CGAffineTransformMakeScale(0.5, 0.5);
} completion:^(BOOL finished) {
self.smallBtn.frame = self.frame;
self.smallBtn.layer.cornerRadius = self.smallBtn.bounds.size.width * 0.5;
self.smallBtn.layer.masksToBounds = YES;
[self.superview addSubview:_smallBtn];
}];
} else if ([anim isEqual:[self.shapeLayer animationForKey:@"showAnimation"]]) {
self.layer.mask = nil;
self.shapeLayer = nil;
}
}
- (UIButton *)smallBtn
{
if (!_smallBtn) {
_smallBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_smallBtn addTarget:self action:@selector(microClick) forControlEvents:UIControlEventTouchUpInside];
}
return _smallBtn;
}
- (void)microClick
{
[self.smallBtn removeFromSuperview];
self.smallBtn = nil;
[UIView animateWithDuration:1.0 animations:^{
self.center = self.headView.center;
self.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
self.bounds = [UIScreen mainScreen].bounds;
self.frame = self.bounds;
CAShapeLayer *shapeLayer = self.shapeLayer;
// 1.获取动画缩放开始时的圆形
UIBezierPath *startPath = [UIBezierPath bezierPathWithOvalInRect:self.headView.frame];
// 2.获取动画缩放结束时的圆形
CGSize endSize = CGSizeMake(self.frame.size.width * 0.5, self.frame.size.height - self.headView.center.y);
CGFloat radius = sqrt(endSize.width * endSize.width + endSize.height * endSize.height);
CGRect endRect = CGRectInset(self.headView.frame, -radius, -radius);
UIBezierPath *endPath = [UIBezierPath bezierPathWithOvalInRect:endRect];
// 3.创建shapeLayer作为视图的遮罩
shapeLayer.path = endPath.CGPath;
// 添加动画
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (id)startPath.CGPath;
pathAnimation.toValue = (id)endPath.CGPath;
pathAnimation.duration = 0.5;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.delegate = self;
pathAnimation.removedOnCompletion = NO;
pathAnimation.fillMode = kCAFillModeForwards;
[shapeLayer addAnimation:pathAnimation forKey:@"showAnmination"];
}];
}
@end
//
// ViewController.m
//
#import "ViewController.h"
#import "ShowContentView.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.view setBackgroundColor:[UIColor greenColor]];
ShowContentView *showView = [[ShowContentView alloc]initWithFrame:self.view.frame];
[showView setBackgroundColor:[UIColor lightGrayColor]];
[self.view addSubview:showView];
}
@end