最近在寫項目集成即時通訊,音視頻修改成類似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