iOS制作带弹跳动画发布界面

项目中经常会用到带弹跳动画发布界面,具体内容如下

效果图:

代码:

// PublishView.m
// UIImage+ImageEffects.h 苹果蒙化图片的分类 pop.h弹跳动画框架 EJExtension.h模型转换框架
// ComposeModel 用于设置按钮文字与图片的模型,在本地设置plist文件保存image(按钮图片)和text(按钮文字)

#import "PublishView.h"
#import "BSVerticalButton.h"
#import "UIImage+ImageEffects.h"
#import "pop.h"
#import "MJExtension.h"
#import "ComposeModel.h"

@interface PublishView ()

/** 取消按钮 */
@property (nonatomic, weak) UIButton *cancelButton;

@end

@implementation PublishView

/** 全局 window_ */
static UIWindow *window_;

/** 显示发布view */
+ (void)show{
  // 添加一个独立的window是为了隔离点击事件
  window_ = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];

  window_.hidden = NO;

  PublishView *publish = [[PublishView alloc]init];

  publish.frame = window_.bounds;

  [window_ addSubview:publish];
}

- (instancetype)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self) {

    UIImageView *imageView = [[UIImageView alloc]initWithImage:[self getEffectImage]];
    [self addSubview:imageView];

    [self setupUI];
  }
  return self;
}

- (void)setupUI{

  //这里用自定义的 window 是为了隔绝点击事件 不让点击事件传到后面控制器的view上去

  // 按钮弹跳动画时让view本身不能点击
  self.userInteractionEnabled = NO;

  // 从plis文件获得一个模型数组
  NSArray *buttonModelArray = [ComposeModel mj_objectArrayWithFilename:@"buttonImage.plist"];

  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 < buttonModelArray.count; ++i) {

    // BSVerticalButton 自定义的垂直排布按钮
    BSVerticalButton *button = [[BSVerticalButton alloc]init];

    button.tag = i;

    [self addSubview:button];

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

    ComposeModel *composeModel = buttonModelArray[i];

    [button setImage:[UIImage imageNamed:composeModel.image] forState:UIControlStateNormal];

    [button setTitle:composeModel.text 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];
  }

  // 添加品牌logo
  UIImageView *topImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"compose_slogan"]];
  topImageView.center = CGPointMake([[UIScreen mainScreen] bounds].size.width * 0.5, [[UIScreen mainScreen] bounds].size.height * 0.2 - [[UIScreen mainScreen] bounds].size.height);

  [self addSubview:topImageView];

  //  POPBasicAnimation  基本的动画
  //  POPSpringAnimation  弹簧动画
  //  POPDecayAnimation  减速动画
  //  POPCustomAnimation  自定义动画

  //创建pop弹簧动画对象
  POPSpringAnimation *animation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];

  animation.beginTime = CACurrentMediaTime() + buttonModelArray.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(@"-------这里可以写动画结束后所要执行的代码...");
    // view本身开启交互
    self.userInteractionEnabled = YES;
  };

  //给顶部的图片添加动画
  [topImageView pop_addAnimation:animation forKey:nil];
  // 底部取消按钮
  UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
  [cancelButton setTitle:@"取 消" forState:UIControlStateNormal];
  cancelButton.titleLabel.font = [UIFont systemFontOfSize:15];
  [cancelButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  [cancelButton setBackgroundColor:[UIColor whiteColor]];
  [cancelButton addTarget:self action:@selector(cancelButtonClick:) forControlEvents:UIControlEventTouchUpInside];
  [self addSubview:cancelButton];
  self.cancelButton = cancelButton;
}

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

  // 退出时执行动画 方法的参数block传空
  [self animationWithBlock:nil];
}

- (void)layoutSubviews{

  [super layoutSubviews];

  // 取消按钮位置大小
  CGPoint center = self.cancelButton.center;
  center.x = self.center.x;
  self.cancelButton.center = center;
  CGRect frame = self.cancelButton.frame;
  frame.origin.y = self.frame.size.height * 0.85;
  frame.size = CGSizeMake(200, 35);
  self.cancelButton.frame = frame;
}

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

  [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;
    }
  }];

}

/** 退出时与点出了某个按钮时执行的弹跳动画后销毁 window_ 移除 这个蒙板 view ,如果block参数completionBlock有值先销毁window_后再执行这个block里的代码块 */
- (void)animationWithBlock:(void (^) ())completionBlock{

  NSLog(@"----%@\n",self.subviews);

  //退出的时候这里用自定义的 window 是为了隔绝点击事件 不让点击事件传到后面控制器的view上去
  // view本身不能点
  self.userInteractionEnabled = NO;

  // 选移除取消按钮
  [self.cancelButton removeFromSuperview];

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

    UIView *view = self.subviews[i];

    //创建pop基本动画对象
    POPBasicAnimation *animation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
    //    POPSpringAnimation *animation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];

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

    // 如果用这个基类 POPBasicAnimation 动画的执行节奏(一开始很慢, 后面很快)
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

    CGPoint center = view.center; //取出中心点

    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(center.x , center.y + [[UIScreen mainScreen] bounds].size.height)];

    if (i == self.subviews.count-1) { //说明是最后一个 view在做动画,就让执行结束的 block
      // 动画结束时调用的 block
      animation.completionBlock = ^(POPAnimation *anim, BOOL finished){

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

        [self removeFromSuperview];

        window_ = nil; //销毁自定义的 window

        !completionBlock ? : completionBlock();
      };
    }
    //给顶部的图片添加动画
    [view pop_addAnimation:animation forKey:nil];
  }
}

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

  [self animationWithBlock:nil];
}

// 获得一个磨纱蒙板 image 图片
- (UIImage *)getEffectImage{
  UIWindow *window = [UIApplication sharedApplication].keyWindow; //获取当前 window
  UIGraphicsBeginImageContext(window.size); //开启window大小的图形上下文
  CGContextRef ref = UIGraphicsGetCurrentContext(); //开启图形上下文
  [window.layer renderInContext:ref]; //把window图层 渲染到图形上下文当中
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); //获取图片
  UIGraphicsEndImageContext(); //关闭图形上下文
  image = [image applyLightEffect]; //调用 image 分类方法 使图片调成蒙板状态
  return image;
}

@end

项目中用到的垂直布局自定义按钮 BSVerticalButton

#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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • iOS仿微信图片分享界面实现代码

    分享功能目前几乎已成为很多app的标配了,其中微信,微博等app的图片分享界面设计的很棒,不仅能够展示缩略图,还可以预览删除.最近我在做一款社交分享app,其中就要实现图文分享功能,于是试着自行实现仿微信分享风格的功能. 核心思想: 主要是使用UICollectionView来动态加载分享图片内容,配合预览页面,实现动态添加和预览删除图片效果. 实现效果: 核心代码如下: 分享界面: // // PostTableViewController.h // NineShare // // Creat

  • IOS实现微信朋友圈相册评论界面的翻转过渡动画

    先来看看实现的类似效果图: 在图片界面点击右下角的查看评论会翻转到评论界面,评论界面点击左上角的返回按钮会反方向翻转回图片界面,真正的实现方法,与传统的导航栏过渡其实只有一行代码的区别,让我们来看看整体的实现. 首先我们实现图片界面,这个界面上有黑色的背景,一张图片和一个查看评论的按钮: - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor blackColor];// 背景设为黑色 //

  • iOS图片界面翻页切换效果

    先看效果: 下面贴代码: #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIImageView *backgroundView; @property (strong,nonatomic) NSArray *array; @end @implementation ViewController -(NSArray *)array { if (_arra

  • iOS高仿微信相册界面翻转过渡动画效果

    点开微信相册的时候,想要在相册图片界面跳转查看点赞和评论时,微信会采用界面翻转的过渡动画来跳转到评论界面,好像是在图片界面的背面一样,点击完成又会翻转回到图片界面,这不同于一般的导航界面滑动动画,觉得很有意思,于是自己学着做了一下,其实也很简单,下面是实现的类似的效果图: 在图片界面点击右下角的查看评论会翻转到评论界面,评论界面点击左上角的返回按钮会反方向翻转回图片界面,真正的实现方法,与传统的导航栏过渡其实只有一行代码的区别,让我们来看看整体的实现. 首先我们实现图片界面,这个界面上有黑色的背

  • Unity iOS混合开发界面切换思路解析

    思路 之前一篇文章里面只谈到了Unity和iOS工程的融合,并没有谈到iOS和Unity界面的切换,这里谈谈思路,Unity导出的iOS工程里面的结构大致是这样的,有一个Window,Window上有一个UnityView,但是并没有控制器,也没有根控制器,虽然在导出的iOS工程中Classes文件夹下的UnityAppController中有rootController的属性,但是上面也标注为空~ 所以,思路就只有一种,,既然Unity导出的iOS工程有一个Window并没有控制器,那好,混合

  • iOS开发之级联界面(推荐界面)搭建原理

    先看看效果图: 一.整体布局  1.项目需求  点击左边cell,右边的cell数据更新  2.界面搭建  2.1交给两个控制器管理比较麻烦,点击一个控制器需要通知另外一个控制器  2. 2因此交给一个控制器管理比较好  2.3用xib搭建,左右各放一个tableView就可以了  3.开发顺序 先做左边的tableView,再做右边的,因为右边的数据是根据左边变化的  二.左边tableView界面搭建  1.自定义cell  左边一个指示器欧一个view   中间位置用label  2.设置

  • iOS实现电商购物车界面示例

    先看界面效果图: 主要实现了商品的展示,并且可以对商品进行多选操作,以及改变商品的购买数量.与此同时,计算出,选中的总价格. 做此类型项目:要注意的:视图与数据要分离开来.视图的展现来源是数据模型层.所以我做的操作就是改变数据层的内容,在根据数据内容,去更新视图界面. 已下是具体实现思路与代码: 1. 实现步骤 在AppDelegate.m中包含ViewController.h头文件,创建ViewController对象(vc),接着创建一个UINavigationController对象(nV

  • iOS中使用UItableviewcell实现团购和微博界面的示例

    使用xib自定义UItableviewcell实现一个简单的团购应用界面布局 一.项目文件结构和plist文件 二.实现效果 三.代码示例 1.没有使用配套的类,而是直接使用xib文件控件tag值操作 数据模型部分: YYtg.h文件 复制代码 代码如下: // //  YYtg.h //  01-团购数据显示(没有配套的类) // //  Created by apple on 14-5-29. //  Copyright (c) 2014年 itcase. All rights reserv

  • IOS 聊天界面(自适应文字)的实现

    该篇文章主要介绍一个实现聊天界面的思路过程,源码可以在 源码链接获得,该工程实现聊天的基本功能,功能还不够完善,欢迎大家提PR,效果图如下所示 我希望通过相对简单的方式实现界面的布局,没有复杂的计算达到自适应的效果. iOS8新功能介绍 虽然self size cell最终没有在我的工程中用到,但是这是我曾经挖过的坑,所以在此做了简单的介绍. 在iOS 8 中,UITableView新增一项功能 self size cells,这是一项通过 UITableViewCell 的约束自动自动计算UI

  • 总结IOS界面间跳转的几种方法

    注意: 下面以FirstViewController(FVC)的按钮button点击后跳转到SecondViewController(SVC)为例说明: 方式一:Storyboard的segues方式 鼠标点击按钮button然后按住control键拖拽到SVC页面,在弹出的segue页面中选择跳转模式即可 优点:操作方便,无代码生成,在storyboard中展示逻辑清晰 缺点:页面较多时不方便查看,团队合作时可维护性差, 多人合作时不建议使用这种方式. 方式二:选项卡UITabBarContr

随机推荐