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的导航架构设计应该 ...
随机推荐
- HDU1502/Luogu1352/UVa1220 party[树形DP]
题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...
- 完全平方数(钟神的hao)
[问题描述] 从1− ?中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数最大可能是多少. [输入格式] 第一行一个数字?. [输出格式] 一行一个整数代表答案对100000007取模之后的答 ...
- java 之前的安全的类回顾,以及以后需要线程安全时使用哪些类
之前所学习到的线程安全的类: StringBuffer:线程安全的可变字符序列.一个类似于 String 的字符串缓冲区,但不能修改. Vector:Vector 类可以实现可增长的对象数组. Has ...
- tyvj[1087]sumsets
描述 正整数N可以被表示成若干2的幂次之和.例如,N = 7时,共有下列6种不同的方案:1) 1+1+1+1+1+1+12) 1+1+1+1+1+23) 1+1+1+2+24) 1+1+1+4 ...
- Java的jar文件安装成windows 服务
Java的jar文件安装成windows 服务: 1.下载:nssm,复制到jar文件目录下 2. jar文件目录下创建bat文件[run.bat],内容为[java -jar 文件名.jar] 3. ...
- Netty 自动重连
from: http://www.dozer.cc/2015/05/netty-auto-reconnect.html 自动重连 用 Netty 写 Client 和 Server 的时候必须要去处理 ...
- IO操作总结
1,读取文件将文件转换为二进制流 InputStream in = new FileInputStream("C:/test.png"); byte[] photo = new b ...
- [转]spring 注入静态变量
原文: http://www.cnblogs.com/xing901022/p/4168124.html 今天碰到一个问题,我的一个工具类提供了几种静态方法,静态方法需要另外一个类的实例提供处理,因此 ...
- vs 2005 thread 无法调试
两种办法:1.打开项目属性,在“Debug”一项里,把“Enable the Visual Studio hosting process”前的钩去掉.这个方法不是好办法.2.打开计算机管理,在服务里将 ...
- cpu负载和利用率
理解Linux系统负荷 linux里的CPU负载