OC实现带弹跳动画按钮的界面控制器view
很多应用都有带弹跳动画发布界面,这里用一个 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
OC实现带弹跳动画按钮的界面控制器view的更多相关文章
- WPF界面设计技巧(3)—实现不规则动画按钮
原文:WPF界面设计技巧(3)-实现不规则动画按钮 发布了定义WPF按钮的教程后,有朋友问能否实现不规则形状的按钮,今天我们就来讲一下不规则按钮的制作. 不规则按钮的做法实际上和先前我们做不规则窗体的 ...
- [转]Android UI:看看Google官方自定义带旋转动画的ImageView-----RotateImageView怎么写(附 图片淡入淡出效果)
http://blog.csdn.net/yanzi1225627/article/details/22439119 众所周知,想要让ImageView旋转的话,可以用setRotation()让其围 ...
- OC导航栏自定义返回按钮
[iOS]让我们一次性解决导航栏的所有问题 在默认情况下,导航栏返回按钮长这个样子 导航栏默认返回按钮 导航栏左上角的返回按钮,其文本默认为上一个ViewController的标题,如果上一个Vi ...
- Android UI:看看Google官方自定义带旋转动画的ImageView-----RotateImageView怎么写(附 图片淡入淡...)
众所周知,想要让ImageView旋转的话,可以用setRotation()让其围绕中心点旋转,但这个旋转是不带动画的,也就是旋转屏幕时图片噌的一下就转过去了,看不到旋转的过程,此UI体验不大好,为此 ...
- iOS开发——项目实战OC篇&类QQ黏性按钮(封装)
类QQ粘性按钮(封装) 那个,先来说说原理吧: 这里原理就是,在界面设置两个控件一个按钮在上面,一个View在下面(同样大小),当我们拖动按钮的时候显示下面的View,view不移动,但是会根据按钮中 ...
- 冒泡动画按钮的简单实现(使用CSS3)
冒泡动画按钮的简单实现(使用CSS3) 原始的参考文章是 http://tutorialzine.com/2010/10/css3-animated-bubble-buttons/ ,基本原理是利用了 ...
- Android使用shape制作圆形控件及添加弹跳动画
--------本来为作者原创,未经同意禁止转载 前言:我们在很多时候都需要在res/drawable文件夹下创建相应的xml文件来为控件添加一些样式效果,比如按钮按下时的按钮样式变化.或者指定按钮的 ...
- bootstrap带图标的按钮与图标做连接
bootstrap通过引入bootstrap的JS与css文件,给元素添加class属性即可. 使用图标只需要加入一个span,class属性设置为对应的图标属性即可.图标对应的class属性可以参考 ...
- uwp - 做一个相对炫酷的动画按钮/按钮动画
原文:uwp - 做一个相对炫酷的动画按钮/按钮动画 看腻了系统自带的button animation何不尝试下自定义一个较为炫酷的动画顺便提升用户体验.效果图: 动画分为几个部分,分别是:内圆从中心 ...
随机推荐
- Dynamics CRM2013/2015 插件注册工具登录后无法显示assembly列表问题的解决办法二
本篇接前面的一篇博文:http://blog.csdn.net/vic0228/article/details/47079717,前篇提供了一种解决方案,将本机系统的语言切换成英文即可,今天再来介绍第 ...
- 07 总结ProgressDialog 异步任务
1,ProgressDialog > //使用对象 设置标题 progressDialog.setTitle("标题"); ...
- [ExtJS5学习笔记]第二节 Sencha Cmd 学习笔记 使你的sencha cmd跑起来
本文地址: http://blog.csdn.net/sushengmiyan/article/details/38313537 本文作者:sushengmiyan ----------------- ...
- UNIX网络编程——非阻塞connect: Web客户程序
非阻塞的connect的实现例子出自Netscape的Web客户程序.客户先建立一个与某个Web服务器的HTTP连接,再获取一个主页.该主页往往含有多个对于其他网页的引用.客户可以使用非阻塞conne ...
- Integration between SharePoint 2013 and CRM 2013 (On-Premise)
具体步骤可见下面的链接 https://community.dynamics.com/crm/b/msdynamicscrmtips/archive/2014/01/27/integration- ...
- 《java入门第一季》之tcp协议下的网络编程
tcp协议相对于udp更加安全. 首先看一下需求:服务器端开启,多个客户端同时向服务器发送数据,看哪个客户端先到达. 说明:这里我开启三个电脑实验,一台电脑写服务器端的程序,两台电脑开客户端的程序.服 ...
- Android项目-高考作文-AsyncTask的不足
1, AsyncTask的不足. 从android4.0开始, 后台只允许一个AsyncTask执行, 如果当前的AsyncTask没有执行完毕, 那么当前的请求一直处于等待状态. 直到上一个执行完毕 ...
- C++ Primer 有感(重载操作符)
1.用于内置类型的操作符,其含义不能改变.也不能为任何内置类型定义额外的新的操作符.(重载操作符必须具有至少一个类类型或枚举类型的操作数.这条规则强制重载操作符不能重新定义用于内置类型对象的操作符的含 ...
- html详解(三)
7.表格标签. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...
- (NO.00001)iOS游戏SpeedBoy Lite成形记(二十四)
我们回到Xcode,打开GameScene.m,首先要添加实例变量: CCNode *_trackLine; 为了根据选中的赛道更新_trackLine的位置,我们添加一个显示方法: -(void)s ...