iOS不得姐项目--pop框架的初次使用
一.pop和Core Animation的区别
1.Core Animation的动画只能添加到layer上
2.pop的动画能添加到任何对象
3.pop的底层并非基于Core Animation,是基于CADisplayLink
4.Core Animation的动画仅仅是表象,并不会真正修改对象的frame/Size等值
5.pop的动画实时修改对象的属性,真正的修改了对象的属性
二.简单结构
三.pop框架简单使用 -- pop不仅可以给layer添加动画,只要是UIView都可以添加动画
1.给view添加动画
2.给layer添加动画
四.项目中的动画效果实现
1.利用pop框架做动画的时候,如果动画关系到了尺寸或者frame,刚开始控件的尺寸或者frame建议不要设置.有时候会出现问题,如下图.由于pop框架做动画是直接修改的属性,所以可以考虑在fromValue中设置尺寸.
2.点击取消按钮的动画,实现思路--直接遍历了控制器中子控件,通过xib添加的控件最早,所以做动画的控件从第2个开始遍历
3.监听按钮的点击 -- 要求是动画依次做完,最后处理对应的事件.
难点:pop框架提供了动画完成的block,自己的目标就是在动画完成后执行相应的事件处理.例如:点击了'发段子'按钮,先做动画,动画完成,跳转到发段子的控制器.
解决方案:抽取方法,将点击取消按钮的动画封装起来,并用block作为参数.点击取消按钮,不需要处理事件,那么block就为nil;如果点击'发段子'之类的按钮,将需要处理的代码用block封装.
- (void)cancleWithBlock:(void(^)())btnClickBlock
{
// 点击了取消之后,动画的过程中就不要处理事件了
self.view.userInteractionEnabled = NO; for (int i = ; i < self.view.subviews.count; i++) { UIView *subView = self.view.subviews[i];
POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; anim.toValue = [NSValue valueWithCGPoint:CGPointMake(subView.centerX, subView.centerY + ChaosScreenH)];
anim.beginTime = CACurrentMediaTime() + (i - ) * ChaosTimeInterval;
anim.duration = 0.25; [subView pop_addAnimation:anim forKey:nil];
// 监听最后一个view动画的完成
if (i == self.view.subviews.count - ) {
[anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) { [self dismissViewControllerAnimated:NO completion:nil];
// 判断点击按钮后要执行的block是否为空
if (btnClickBlock) {
btnClickBlock();
}
}];
}
}
} - (IBAction)cancelClick {
[self cancleWithBlock:nil];
} - (void)buttonClick:(UIButton *)button
{
[self cancleWithBlock:^{
if (button.tag == ) {
ChaosLog(@"发视频");
} else if (button.tag == ){
ChaosLog(@"发图片");
} else if (button.tag == ){
ChaosLog(@"发段子");
} else if (button.tag == ){
ChaosLog(@"发声音");
}
}];
}
五.最后是项目中的代码
#import "ChaosPublishViewController.h"
#import "ChaosVerticalButton.h" #import <POP.h> @interface ChaosPublishViewController () @end
@implementation ChaosPublishViewController static CGFloat const ChaosTimeInterval = 0.1;
static CGFloat const ChaosAnimSpeed = ; - (void)viewDidLoad {
[super viewDidLoad]; // 先让所有不能处理事件
self.view.userInteractionEnabled = NO;
// 数据
NSArray *images = @[@"publish-video", @"publish-picture", @"publish-text", @"publish-audio", @"publish-review", @"publish-offline"];
NSArray *titles = @[@"发视频", @"发图片", @"发段子", @"发声音", @"审帖", @"离线下载"]; // 设置按钮位置
CGFloat buttonW = ;
CGFloat buttonH = buttonW + ;
CGFloat startY = (ChaosScreenH - * buttonH) * 0.5;
CGFloat startX = ;
NSInteger maxCols = ; // 列数
CGFloat buttonMargin = (ChaosScreenW - * startX - maxCols * buttonW) / (maxCols - );
// 添加发布类别
for (int i = ; i < images.count; i++) {
ChaosVerticalButton *button = [[ChaosVerticalButton alloc] init];
// button.width = buttonW; // 用了pop后,直接修改了按钮的frame,这里可以先不用设置
// button.height = buttonH; // 设置了动画效果反而不好
[button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
[button setTitle:titles[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:];
button.tag = i;
// 添加点击事件
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
NSInteger btnRow = i / maxCols; // 按钮所在行
NSInteger btnCol = i % maxCols; // 按钮所在列
CGFloat buttonEndY = startY + btnRow * buttonH; // 按钮最终Y值
CGFloat buttonX = startX + btnCol * (buttonMargin + buttonW); // 按钮X值 [self.view addSubview:button]; // 设置动画
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
anim.fromValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonEndY - ChaosScreenH, buttonW, buttonH)];
anim.toValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonEndY, buttonW, buttonH)];
// anim.springBounciness = 8;
anim.springSpeed = ChaosAnimSpeed;
anim.beginTime = CACurrentMediaTime() + i * ChaosTimeInterval;
[button pop_addAnimation:anim forKey:nil];
} // 添加标语
[self setupSlogan];
} - (void)setupSlogan
{
// 添加标语
UIImageView *sloganImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"app_slogan"]];
sloganImageView.y = -;
[self.view addSubview:sloganImageView]; CGFloat centerX = ChaosScreenW * 0.5;
CGFloat centerEndY = ChaosScreenH * 0.2;
CGFloat centerBeginY = centerEndY - ChaosScreenH;
// 设置动画
POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(centerX, centerBeginY)];
anim.toValue = [NSValue valueWithCGPoint:CGPointMake(centerX, centerEndY)];;
// anim.springBounciness = 8;
anim.springSpeed = ChaosAnimSpeed;
anim.beginTime = CACurrentMediaTime() + * ChaosTimeInterval;
[anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
// 动画完成恢复处理事件的能力
self.view.userInteractionEnabled = YES;
}];
[sloganImageView pop_addAnimation:anim forKey:nil];
} - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self cancleWithBlock:nil];
} - (void)cancleWithBlock:(void(^)())btnClickBlock
{
// 点击了取消之后,动画的过程中就不要处理事件了
self.view.userInteractionEnabled = NO; for (int i = ; i < self.view.subviews.count; i++) { UIView *subView = self.view.subviews[i];
POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; anim.toValue = [NSValue valueWithCGPoint:CGPointMake(subView.centerX, subView.centerY + ChaosScreenH)];
anim.beginTime = CACurrentMediaTime() + (i - ) * ChaosTimeInterval;
anim.duration = 0.25; [subView pop_addAnimation:anim forKey:nil];
// 监听最后一个view动画的完成
if (i == self.view.subviews.count - ) {
[anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) { [self dismissViewControllerAnimated:NO completion:nil];
// 判断点击按钮后要执行的block是否为空
if (btnClickBlock) {
btnClickBlock();
}
}];
}
}
} - (IBAction)cancelClick {
[self cancleWithBlock:nil];
} - (void)buttonClick:(UIButton *)button
{
[self cancleWithBlock:^{
if (button.tag == ) {
ChaosLog(@"发视频");
} else if (button.tag == ){
ChaosLog(@"发图片");
} else if (button.tag == ){
ChaosLog(@"发段子");
} else if (button.tag == ){
ChaosLog(@"发声音");
}
}];
} @end
iOS不得姐项目--pop框架的初次使用的更多相关文章
- iOS不得姐项目--appearance的妙用,再一次设置导航栏返回按钮,导航栏左右按钮的封装(巧用分类)
一.UI_APPEARANCE_SELECTOR 彩票项目中appearance的用法一直没有搞明白,这次通过第二个项目中老师的讲解,更深一层次的了解到了很多关于appearance的作用以及使用方法 ...
- iOS不得姐项目--TabBar的重复点击实现当前模块刷新;状态栏点击实现当前模块回滚到最顶部
一.实现功能:重复点击tabBar,刷新当前TableView,其余不受影响 <1>实现思路: 错误的方法: TabBar成为自己的代理,监听自己的点击--这种方法是不可取的,如果外面设置 ...
- iOS不得姐项目--精华模块上拉下拉的注意事项,日期显示,重构子控制器,计算cell的高度(只计算一次),图片帖子的显示
一.上拉下拉注意事项 使用MJRefresh中的上拉控件自动设置透明 当请求下页数据通过page的时候,注意的是上拉加载更多数据失败的问题,下拉加载数据失败了,页数应该还原.或者是请求成功的时候再将页 ...
- iOS不得姐项目--推荐关注模块(一个控制器控制两个tableView),数据重复请求的问题,分页数据的加载,上拉下拉刷新(MJRefresh)
一.推荐关注模块(一个控制器控制两个tableView) -- 数据的显示 刚开始加载数据值得注意的有以下几点 导航控制器会自动调整scrollView的contentInset,最好是取消系统的设置 ...
- iOS不得姐项目--封装状态栏指示器(UIWindow实现)
一.头文件 #import <UIKit/UIKit.h> @interface ChaosStatusBarHUD : NSObject /** 显示成功信息 */ + (void)sh ...
- iOS不得姐项目--图片帖子模块,大图默认显示最顶部分的处理
一.刚开始的处理,设置Mode属性(self.pictureImageView.contentMode = UIViewContentModeScaleAspectFill;) 和 Clip Subv ...
- iOS不得姐项目--登录模块的布局,设置文本框占位文字颜色,自定义内部控件竖直排列的按钮
一.登录模块的布局 将一整部分切割成若干部分来完成,如图分成了三部分来完成 设置顶部状态栏为白色的方法 二.设置文本框占位文字颜色 <1>方法一与方法二实现原理是同一种,都是通过设置pla ...
- 手把手教你如何搭建iOS项目基本框架
手把手教你如何搭建iOS项目基本框架 今天我们来谈谈如何搭建框架,框架需要做一些什么. 第一步:找到我们的目标我们的目标是让其他开发人员拿到手后即可写页面,不再需要考虑其他的问题. 第二步:我们需要做 ...
- iOS项目——基本框架搭建
项目开发过程中,在完成iOS项目——项目开发环境搭建之后,我们首先需要考虑的就是我们的项目的整体框架与导航架构设计,然后在这个基础上考虑功能模块的完成. 一 导航架构设计 一款App的导航架构设计应该 ...
随机推荐
- form表单验证和事件、正则表达式
1.表单验证<form></form> (1).非空验证(去空格) (2).对比验证(跟一个值对比) (3).范围验证(根据一个范围进行判断) (4).固定格式验证:电话号码, ...
- [No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock
操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock 可以操刀了—从纸上到实际 从Linux 0.11 那里学点东西… 读磁盘 ...
- JS常用方法函数整理
1.document.write("");为输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document->html->(head,body) 4. ...
- vue组件的配置属性
vue组件的声明语法: Vue.component('component-name',{ template:'<p>段落{{prop1}} {{prop2}}</p>', da ...
- S2总结笔记
第一章:深入.NET框架 1..NET FrameWork两大组件是什么? 解析:.NET 框架类库(FCL:FrameWork Class Library)和公共语言运行时(CLR:common l ...
- 毫米转换为PX
公式:毫米数/25.4*你的电脑的DPI,win7 DPI 100%缩放为96,125%为120,150%为144,200%为192 象素数 / DPI = 英寸数 英寸数 * 25.4 = 毫米数
- ssh 免密码设置失败原因总结
先复习一下设置ssh免密码操作的步骤: 进入主目录 cd 生成公钥 ssh-keygen -t rsa -P '' (注:最后是二个单引号,表示不设置密码) 然后分发公钥到目标机器 ssh-copy- ...
- Spring 4.0.2 学习笔记(2) - 自动注入及properties文件的使用
接上一篇继续, 学习了基本的注入使用后,可能有人会跟我一样觉得有点不爽,Programmer的每个Field,至少要有一个setter,这样spring配置文件中才能用<property> ...
- tomcat 新手上路
前提:本机先安装好JDK,保证常规java环境已经具备 1.下载Tomcat 7.0现在官网上好象已经没有安装程序版了,只有免解压zip版本(现在最新的版本是7.0.42) 下载地址 http://t ...
- ubuntu-12.10-server中打开终端的方式
ubuntu-12.10-server系统在图形界面的任务栏上找不到终端的踪影,可以使用以下两种方式调出 1.在图形界面中点击Dash Home 点击后搜索terminal即可 2.可以通过快捷键CT ...