iOS不得姐项目--pop框架的初次使用

一.pop和Core Animation的区别

  1.Core Animation的动画只能添加到layer上

  2.pop的动画能添加到任何对象

  3.pop的底层并非基于Core Animation,是基于CADisplayLink

  4.Core Animation的动画仅仅是表象,并不会真正修改对象的frame/Size等值

  5.pop的动画实时修改对象的属性,真正的修改了对象的属性

二.简单结构

iOS不得姐项目--pop框架的初次使用

三.pop框架简单使用 -- pop不仅可以给layer添加动画,只要是UIView都可以添加动画

  1.给view添加动画

iOS不得姐项目--pop框架的初次使用

  2.给layer添加动画

iOS不得姐项目--pop框架的初次使用

四.项目中的动画效果实现

  1.利用pop框架做动画的时候,如果动画关系到了尺寸或者frame,刚开始控件的尺寸或者frame建议不要设置.有时候会出现问题,如下图.由于pop框架做动画是直接修改的属性,所以可以考虑在fromValue中设置尺寸.

iOS不得姐项目--pop框架的初次使用

  2.点击取消按钮的动画,实现思路--直接遍历了控制器中子控件,通过xib添加的控件最早,所以做动画的控件从第2个开始遍历

iOS不得姐项目--pop框架的初次使用

  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不得姐项目--封装状态栏指示器(UIWindow实现)


下一篇:iOS不得姐项目--appearance的妙用,再一次设置导航栏返回按钮,导航栏左右按钮的封装(巧用分类)