全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

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


# iOS弹跳动画  # iOS弹跳动画界面  # iOS动画发布界面  # 总结IOS界面间跳转的几种方法  # iOS图片界面翻页切换效果  # iOS仿微信图片分享界面实现代码  # IOS 聊天界面(自适应文字)的实现  # iOS中使用UItableviewcell实现团购和微博界面的示例  # iOS实现电商购物车界面示例  # IOS实现微信朋友圈相册评论界面的翻转过渡动画  # Unity iOS混合开发界面切换思路解析  # iOS高仿微信相册界面翻转过渡动画效果  # iOS开发之级联界面(推荐界面)搭建原理  # 自定义  # 是为了  # 行号  # 所要  # 移除  # 蒙板  # 离线  # 结束后  # 出了  # 最多  # 中心点  # 相对于  # 图层  # 很慢  # 结束时  # 具体内容  # 大家多多  # 调成  # 中经  # button_h 


相关文章: 如何在企业微信快速生成手机电脑官网?  建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略  无锡营销型网站制作公司,无锡网选车牌流程?  制作网站的基本流程,设计网站的软件是什么?  香港服务器WordPress建站指南:SEO优化与高效部署策略  网站制作多少钱一个,建一个论坛网站大约需要多少钱?  建站org新手必看:2024最新搭建流程与模板选择技巧  制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?  简历在线制作网站免费版,如何创建个人简历?  家庭建站与云服务器建站,如何选择更优?  可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?  如何在IIS中配置站点IP、端口及主机头?  建站之星如何助力企业快速打造五合一网站?  如何在阿里云香港服务器快速搭建网站?  高端网站建设与定制开发一站式解决方案 中企动力  网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?  电商网站制作公司有哪些,1688网是什么意思?  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  如何用狗爹虚拟主机快速搭建网站?  制作宣传网站的软件,小红书可以宣传网站吗?  网站制作公司广州有几家,广州尚艺美发学校网站是多少?  寿县云建站:智能SEO优化与多行业模板快速上线指南  如何在Windows虚拟主机上快速搭建网站?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  高防服务器租用首荐平台,企业级优惠套餐快速部署  我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?  建站之星导航配置指南:自助建站与SEO优化全解析  较简单的网站制作软件有哪些,手机版网页制作用什么软件?  已有域名和空间如何搭建网站?  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  Swift中swift中的switch 语句  建站之星logo尺寸如何设置最合适?  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  建站之星手机一键生成:多端自适应+小程序开发快速建站指南  如何通过免费商城建站系统源码自定义网站主题与功能?  七夕网站制作视频,七夕大促活动怎么报名?  头像制作网站在线制作软件,dw网页背景图像怎么设置?  如何快速上传建站程序避免常见错误?  南阳网站制作公司推荐,小学电子版试卷去哪里找资源好?  高端云建站费用究竟需要多少预算?  ,石家庄四十八中学官网?  C++中引用和指针有什么区别?(代码说明)  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  如何快速搭建支持数据库操作的智能建站平台?  高防服务器租用指南:配置选择与快速部署攻略  学校建站服务器如何选型才能满足性能需求?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  如何快速查询域名建站关键信息?  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。