視圖收起動畫

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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章