很多应用都有带弹跳动画发布界面,这里用一个 UIViewController 实现这种效果,外界只要 modal出不带动画这个控制器就可以实现

#import "BSPublishVC.h"

#import "BSVerticalButton.h"

#import <POP.h>

 

@interface BSPublishVC ()

 

@end

 

@implementation BSPublishVC

 

- (void)viewDidLoad {

    [super viewDidLoad];

    //背景图征

    UIImageView *imageView = [[UIImageView alloc]init];

    imageView.frame = [UIScreen mainScreen].bounds;

    // shareBottomBackground

    imageView.image = [UIImage imageNamed:@"shareBottomBackground"];

    imageView.contentMode = UIViewContentModeScaleToFill;

    [self.view addSubview:imageView];

    

    //退出按钮

    UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];

    [cancelButton setTitle:@"退出" forState:UIControlStateNormal];

    [cancelButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

    [cancelButton setBackgroundImage:[UIImage imageNamed:@"FollowBtnBg"] forState:UIControlStateNormal];

    [cancelButton setBackgroundImage:[UIImage imageNamed:@"FollowBtnClickBg"] forState:UIControlStateHighlighted];

    CGRect frame = cancelButton.frame;

    frame.size = CGSizeMake(200, 30);

    frame.origin.y = [UIScreen mainScreen].bounds.size.height * 0.8;

    cancelButton.frame = frame;

    CGPoint point = cancelButton.center;

    point.x = [UIScreen mainScreen].bounds.size.width * 0.5;

    cancelButton.center = point;

    [cancelButton addTarget:self action:@selector(cancelButtonClick) forControlEvents:UIControlEventTouchUpInside];

    [imageView addSubview:cancelButton];

    

    

    //让一开始动画时不让控制的view失去交互,那这时在做动时点击按钮等都不会起作用

    self.view.userInteractionEnabled = NO;

    

    NSArray *buttonImages = @[@"publish-video",@"publish-picture",@"publish-text",@"publish-audio",@"publish-review",@"publish-offline"];

    NSArray *buttonTitles = @[@"发视频",@"发图片",@"发段子",@"发声音",@"审贴子",@"离线下载"];

    

    CGFloat button_w = 72;

    CGFloat button_h = button_w + 30;

    NSInteger maxLoc = 3; //最多列数

    

    //按钮弹跳动画停止后的起始 y 值

    CGFloat buttonEnd_y = ([[UIScreen mainScreen] bounds].size.height - button_h * 2) / 2;

    

    //最开始在屏幕外上方的的起始 y 值

    CGFloat buttonBegin_y = buttonEnd_y - [[UIScreen mainScreen] bounds].size.height;

    

    //按钮的起始间隙值

    CGFloat buttonStartMargin = 20;

    

    //中间的一个按钮相对于两边按钮的间隙

    CGFloat buttonMargin = ([[UIScreen mainScreen] bounds].size.width - buttonStartMargin * 2 - button_w * maxLoc) / (maxLoc - 1);

    

    for (NSInteger i = 0; i < buttonImages.count; ++i) {

        

        BSVerticalButton *button = [[BSVerticalButton alloc]init];

        

        button.tag = i;

        

        [self.view addSubview:button];

        

        [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];

        

        [button setImage:[UIImage imageNamed:buttonImages[i]] forState:UIControlStateNormal];

        

        [button setTitle:buttonTitles[i] forState:UIControlStateNormal];

        

        [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

        

        button.titleLabel.font = [UIFont systemFontOfSize:14];

        

        NSInteger loc = i % maxLoc;   //例号

        NSInteger row = i / maxLoc;   //行号

        

        CGFloat button_x = buttonStartMargin + loc * (button_w + buttonMargin);

        CGFloat buttonBginAnimation_y = buttonBegin_y + (button_h * row); //弹跳前的 y 值

        CGFloat buttonEndAnimation_y = buttonEnd_y + (button_h * row); //弹跳后的 y 值

        

        //创建pop弹簧动画对象

        POPSpringAnimation *animation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];

        

        animation.beginTime = CACurrentMediaTime() + i * 0.1; //动画开始时间

        

        animation.springBounciness = 10; //弹簧增强 0-20

        

        animation.springSpeed = 8; //弹簧速度 0-20

        

        animation.fromValue = [NSValue valueWithCGRect:CGRectMake(button_x, buttonBginAnimation_y, button_w, button_h)];

        

        animation.toValue = [NSValue valueWithCGRect:CGRectMake(button_x, buttonEndAnimation_y, button_w, button_h)];

        

        //中间的按钮添加动画

        [button pop_addAnimation:animation forKey:nil];

    }

    

    UIImageView *topImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"app_slogan"]];

    topImageView.center = CGPointMake([[UIScreen mainScreen] bounds].size.width * 0.5, [[UIScreen mainScreen] bounds].size.height * 0.2 - [[UIScreen mainScreen] bounds].size.height);

    

    

    [self.view addSubview:topImageView];

    

    //创建pop弹簧动画对象

    POPSpringAnimation *animation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];

    

    animation.beginTime = CACurrentMediaTime() + buttonImages.count * 0.001; //动画开始时间

    

    animation.springBounciness = 10; //弹簧增强 0-20

    

    animation.springSpeed = 10; //弹簧速度 0-20

    

    CGFloat center_x = [[UIScreen mainScreen] bounds].size.width * 0.5;

    CGFloat endCenter_y = [[UIScreen mainScreen] bounds].size.height * 0.2;

    CGFloat beginCenter_y = endCenter_y - [[UIScreen mainScreen] bounds].size.height;

    

    animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(center_x, beginCenter_y)];

    

    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(center_x, endCenter_y)];

    

    animation.completionBlock = ^(POPAnimation *anim, BOOL finished){

        NSLog(@"-------这里可以写动画结束后所要执行的代码...");

        

        self.view.userInteractionEnabled = YES; //动画完时让view开启交互

    };

    

    //给顶部的图片添加动画

    [topImageView pop_addAnimation:animation forKey:nil];

}

 

- (void)buttonClick:(UIButton *)button{

    

    [self cancelButtonClick];

    

    [self animationWithBlock:^{

        switch (button.tag) {

            case 0:

                NSLog(@"发视频");

                break;

            case 1:

                NSLog(@"发图片");

                break;

            case 2:

                NSLog(@"发段子");

                break;

            case 3:

                NSLog(@"发声音");

                break;

            case 4:

                NSLog(@"审贴子");

                break;

            case 5:

                NSLog(@"离线下载");

                break;

            default:

                break;

        }

    }];

    

}

 

// 退出发布界面的动画

- (void)animationWithBlock:(void (^) ())completionBlock{

    

    //退出时也不让所有的按钮或view能点击

    self.view.userInteractionEnabled = NO;

    

    for (NSInteger i = 1; i < self.view.subviews.count; ++i) {

        

        UIView *view = self.view.subviews[i];

        

        //创建pop基本动画对象

        POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];

        //        POPSpringAnimation *animation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];

        

        animation.beginTime = CACurrentMediaTime() + (i - 1) * 0.085; //动画开始时间

        

        // 如果用这个基类 POPBasicAnimation  动画的执行节奏(一开始很慢, 后面很快)

        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

        

        CGPoint center = view.center;

        CGRect frame = view.frame;

        animation.toValue = [NSValue valueWithCGPoint:CGPointMake(center.x,  frame.origin.y + SCREEN_H)];

        

        if (i == self.view.subviews.count - 1) { //说明是最后一个 view在做动画,就让执行结束的 block

            // 动画结束时调用的 block

            animation.completionBlock = ^(POPAnimation *anim, BOOL finished){

                

                NSLog(@"取消时 这里可以写动画结束后所要执行的代码...");

                [self dismissViewControllerAnimated:NO completion:nil];

                

                if (completionBlock) {

                    completionBlock();

                }

                //                !completionBlock ? : completionBlock();

            };

        }

        //给顶部的图片添加动画

        [view pop_addAnimation:animation forKey:nil];

    }

}

 

- (void)cancelButtonClick{

    

    [self animationWithBlock:nil];

}

 

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    

    [self animationWithBlock:nil];

}

@end

 

BSVerticalButton.h 自定义的垂直排布按钮

#import "BSVerticalButton.h"

 

@implementation BSVerticalButton

 

- (instancetype)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self) {

        [self setupUI];

    }

    return self;

}

 

- (void)awakeFromNib{

    [super awakeFromNib];

    [self setupUI];

}

  

- (void)setupUI{

    self.titleLabel.textAlignment = NSTextAlignmentCenter;

}

 

- (void)layoutSubviews{

    [super layoutSubviews];

    

    //按钮内部图片 frame

    CGRect imageViewFrame = self.imageView.frame;

    imageViewFrame.origin.x = 0;

    imageViewFrame.origin.y = 0;

    imageViewFrame.size.width = self.bounds.size.width;

    imageViewFrame.size.height = self.bounds.size.width;

    self.imageView.frame = imageViewFrame;

    

    //按钮内部label frame

    CGRect titleLabelFrame = self.titleLabel.frame;

    titleLabelFrame.origin.x = 0;

    titleLabelFrame.origin.y = self.imageView.frame.size.height + 10;

    titleLabelFrame.size.width = self.bounds.size.width;

    self.titleLabel.frame = titleLabelFrame;

    

    //按钮自身大小

    CGRect buttonBounds = self.bounds;

    buttonBounds.size.width = self.imageView.frame.size.width;

    buttonBounds.size.height = self.imageView.bounds.size.height + self.titleLabel.bounds.size.height + 10;

    self.bounds = buttonBounds;

}

@end

posted on 2017-07-14 17:44  chennet  阅读(716)  评论(0编辑  收藏  举报