POP动画[2]

POP动画[2]

1:定制控制器间的转场动画.

源码有点多-_-!!

//
// RootViewController.h
// Animation
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController

@end

RootViewController.h

//
// RootViewController.m
// Animation
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"

#import "ModelViewController.h"
#import "PresentingAnimator.h"
#import "DismissingAnimator.h"

#import "POP.h"

@interface RootViewController ()<UIViewControllerTransitioningDelegate>

@end

@implementation RootViewController

- (void)viewDidLoad
{
[super viewDidLoad];

UIButton *presentButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 150, 50)];
[self.view addSubview:presentButton];
presentButton.center = self.view.center;
presentButton.layer.cornerRadius = 5.f;
presentButton.backgroundColor = [UIColor redColor];

[presentButton setTitle:@"推出控制器"
forState:UIControlStateNormal];

// 添加button事件
[presentButton addTarget:self
action:@selector(present:)
forControlEvents:UIControlEventTouchUpInside];
}

- (void)present:(id)sender
{
// 推出控制器
ModelViewController *modalViewController = [ModelViewController new];

// 设置转场动画代理
modalViewController.transitioningDelegate = self;

// 定制转场动画
modalViewController.modalPresentationStyle = UIModalPresentationCustom;

[self.navigationController presentViewController:modalViewController
animated:YES
completion:NULL];
}

#pragma mark - UIViewControllerTransitioningDelegate

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting
sourceController:(UIViewController *)source
{
// 推出控制器的动画
return [PresentingAnimator new];
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
// dismissing控制器的动画
return [DismissingAnimator new];
}

@end

RootViewController.m

//
// ModelViewController.h
// Animation
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ModelViewController : UIViewController

@end

ModelViewController.h

//
// ModelViewController.m
// Animation
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "ModelViewController.h"

@interface ModelViewController ()

@end

@implementation ModelViewController

- (void)viewDidLoad
{
[super viewDidLoad];

self.view.layer.cornerRadius = 8.f;
self.view.backgroundColor = [UIColor blackColor];
[self addDismissButton];
}

- (void)addDismissButton
{
UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeSystem];
dismissButton.translatesAutoresizingMaskIntoConstraints = NO;
dismissButton.tintColor = [UIColor whiteColor];
dismissButton.titleLabel.font = [UIFont fontWithName:@"Avenir" size:20];
[dismissButton setTitle:@"Dismiss" forState:UIControlStateNormal];
[dismissButton addTarget:self
action:@selector(dismiss:)
forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:dismissButton];

// 自动布局
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:dismissButton
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.f
constant:0.f]];

// 自动布局
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[dismissButton]-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(dismissButton)]];
}

- (void)dismiss:(id)sender
{
[self dismissViewControllerAnimated:YES
completion:nil];
}

@end

ModelViewController.m

//
// PopAnimator.h
// Popping
//
// Created by André Schneider on 14.05.14.
// Copyright (c) 2014 André Schneider. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface PresentingAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

PresentingAnimator.h

//
// PopAnimator.m
// Popping
//
// Created by André Schneider on 14.05.14.
// Copyright (c) 2014 André Schneider. All rights reserved.
//

#import "PresentingAnimator.h"
#import "POP.h"

@implementation PresentingAnimator

// 转场动画时间
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.5f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
// 获取原始控制器的View
UIView *fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;

fromView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
fromView.userInteractionEnabled = NO;

// 获取推出控制器的View
UIView *toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
toView.frame = CGRectMake(0, 0,
CGRectGetWidth(transitionContext.containerView.bounds) - 104.f,
CGRectGetHeight(transitionContext.containerView.bounds) - 288.f);

// 设置toView的初始的位置
toView.center = CGPointMake(transitionContext.containerView.center.x,
-transitionContext.containerView.center.y);

// 用来让背景变暗的动画效果
UIView *dimmingView = [[UIView alloc] initWithFrame:fromView.bounds];
dimmingView.backgroundColor = [UIColor blackColor];
dimmingView.layer.opacity = 0.0;

// 添加的转场动画容器当中
[transitionContext.containerView addSubview:dimmingView];
[transitionContext.containerView addSubview:toView];

// 位置动画(Spring系列)
POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
positionAnimation.toValue = @(transitionContext.containerView.center.y);
positionAnimation.springBounciness = 10;
[positionAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {

// 动画结束后记得设置这个参数
[transitionContext completeTransition:YES];
}];

// 缩放动画(Spring系列)
POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.springBounciness = 20;
scaleAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(1.2, 1.4)];

// 透明度动画(基本动画系列)
POPBasicAnimation *opacityAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerOpacity];
opacityAnimation.toValue = @(0.7);

// 添加动画
[toView.layer pop_addAnimation:positionAnimation
forKey:@"positionAnimation"];

[toView.layer pop_addAnimation:scaleAnimation
forKey:@"scaleAnimation"];

[dimmingView.layer pop_addAnimation:opacityAnimation
forKey:@"opacityAnimation"];
}

@end


PresentingAnimator.m

//
// DismissingAnimator.h
// Popping
//
// Created by André Schneider on 16.05.14.
// Copyright (c) 2014 André Schneider. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface DismissingAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

DismissingAnimator.h

//
// DismissingAnimator.m
// Popping
//
// Created by André Schneider on 16.05.14.
// Copyright (c) 2014 André Schneider. All rights reserved.
//

#import "DismissingAnimator.h"
#import "POP.h"

@implementation DismissingAnimator

// 转场动画时间
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.5f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
/*
- 在Dismiss动画中,transitionContext.containerView.subviews里面包含了
- 之前添加进去的View哦,这点很重要
*/

// 开启toVC的用户交互
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
toVC.view.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
toVC.view.userInteractionEnabled = YES;

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

// 找到刚刚的那个用于改变透明度的View
__block UIView *dimmingView;
[transitionContext.containerView.subviews enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {
if (view.layer.opacity < 1.f) {
dimmingView = view;
*stop = YES;
}
}];

// 改变透明度动画(基本动画类型)
POPBasicAnimation *opacityAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerOpacity];
opacityAnimation.toValue = @(0.0);

// 改变位置动画(基本类型)
POPBasicAnimation *offscreenAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY];

offscreenAnimation.toValue = @(-fromVC.view.layer.position.y);
[offscreenAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
// 通知动画结束
[transitionContext completeTransition:YES];
}];

// 执行动画
[fromVC.view.layer pop_addAnimation:offscreenAnimation forKey:@"offscreenAnimation"];
[dimmingView.layer pop_addAnimation:opacityAnimation forKey:@"opacityAnimation"];
}

@end


DismissingAnimator.m

2:TableView动画

//
// RootTableViewController.h
// POPTableView
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface RootTableViewController : UITableViewController

@end

RootTableViewController.h

//
// RootTableViewController.m
// POPTableView
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootTableViewController.h"
#import "PopTableViewCell.h"

@interface RootTableViewController ()

@end

@implementation RootTableViewController

- (void)viewDidLoad
{
[super viewDidLoad];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 50;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *resuseID = @"YouXianMing";

PopTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:resuseID];

if (cell == nil)
{
cell = [[PopTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:resuseID];
}

cell.showTitle.text = @"YouXianMing";

cell.selectionStyle = UITableViewCellSelectionStyleNone;

return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}

@end

RootTableViewController.m

//
// PopTableViewCell.h
// POPTableView
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface PopTableViewCell : UITableViewCell

@property (nonatomic, strong) UILabel *showTitle;

@end

PopTableViewCell.h

//
// PopTableViewCell.m
// POPTableView
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "PopTableViewCell.h"
#import "POP.h"

@implementation PopTableViewCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
_showTitle = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
[self addSubview:_showTitle];

_showTitle.textAlignment = NSTextAlignmentCenter;
_showTitle.font = [UIFont fontWithName:@"HelveticaNeue-Thin"
size:20.f];
}
return self;
}

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];

if (self.highlighted)
{
// 选中时动画
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewScaleXY];
scaleAnimation.duration = 0.1;
scaleAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(0.85, 0.85)];
[_showTitle pop_addAnimation:scaleAnimation forKey:@"scaleAnimation"];
}
else
{
// 没有选中或者再次显示时的动画
POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(1, 1)];
scaleAnimation.velocity = [NSValue valueWithCGPoint:CGPointMake(3, 3)];
scaleAnimation.springBounciness = 20.f;
[_showTitle pop_addAnimation:scaleAnimation forKey:@"scaleAnimation"];
}
}

@end

PopTableViewCell.m

这个地方才是动画效果的关键哦:).

3:高逼格按钮动画


//
// RootViewController.m
// ButtonAnimation
//
// Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "CAShapeLayer+Circle.h"
#import "POP.h"

@interface RootViewController ()<POPAnimationDelegate>

@property (nonatomic, strong) UIButton *button;
@property (nonatomic, strong) CAShapeLayer *circleShape1;
@property (nonatomic, strong) CAShapeLayer *circleShape2;

@end

@implementation RootViewController

- (void)viewDidLoad
{
[super viewDidLoad];

// 圆环1
_circleShape1 = [CAShapeLayer LayerWithCircleCenter:self.view.center
radius:70.f
startAngle:DEGREES(0)
endAngle:DEGREES(360)
clockwise:YES
lineDashPattern:nil];
_circleShape1.lineWidth = 3.f;
_circleShape1.strokeColor = [UIColor cyanColor].CGColor;
_circleShape1.strokeEnd = 0.f;
[self.view.layer addSublayer:_circleShape1];

// 圆环2
_circleShape2 = [CAShapeLayer LayerWithCircleCenter:self.view.center
radius:90.f
startAngle:DEGREES(0)
endAngle:DEGREES(360)
clockwise:NO
lineDashPattern:nil];
_circleShape2.lineWidth = 1.f;
_circleShape2.strokeColor = [UIColor magentaColor].CGColor;
_circleShape2.strokeEnd = 0.f;
[self.view.layer addSublayer:_circleShape2];

// 完整显示按住按钮后的动画效果
_button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
_button.layer.cornerRadius = 50.f;
_button.backgroundColor = [UIColor cyanColor];
_button.center = self.view.center;
[self.view addSubview:_button];

// 按住按钮后没有松手的动画
[_button addTarget:self
action:@selector(scaleToSmall)
forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter];

// 按住按钮松手后的动画
[_button addTarget:self
action:@selector(scaleAnimations)
forControlEvents:UIControlEventTouchUpInside];

// 按住按钮后拖拽出去的动画
[_button addTarget:self
action:@selector(scaleToDefault)
forControlEvents:UIControlEventTouchDragExit];
}

- (void)scaleToSmall
{
// 变小尺寸
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(0.7f, 0.7f)];
scaleAnimation.delegate = self; // 核心
[_button.layer pop_addAnimation:scaleAnimation forKey:nil];

// 颜色
POPSpringAnimation *backgroundColor = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBackgroundColor];
backgroundColor.toValue = (id)[UIColor magentaColor].CGColor;
[_button.layer pop_addAnimation:backgroundColor forKey:@"magentaColor"];
}

- (void)scaleAnimations
{
// 恢复尺寸
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
scaleAnimation.delegate = self; // 核心
[_button.layer pop_addAnimation:scaleAnimation forKey:nil];

// 颜色
POPSpringAnimation *backgroundColor = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBackgroundColor];
backgroundColor.toValue = (id)[UIColor cyanColor].CGColor;
[_button.layer pop_removeAnimationForKey:@"magentaColor"]; // 先移除再添加
[_button.layer pop_addAnimation:backgroundColor forKey:nil];
}

- (void)scaleToDefault
{
// 恢复尺寸
POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
scaleAnimation.delegate = self; // 核心
[_button.layer pop_addAnimation:scaleAnimation forKey:nil];

// 颜色
POPSpringAnimation *backgroundColor = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBackgroundColor];
backgroundColor.toValue = (id)[UIColor cyanColor].CGColor;
[_button.layer pop_removeAnimationForKey:@"magentaColor"]; // 先移除再添加
[_button.layer pop_addAnimation:backgroundColor forKey:nil];
}

// 代理
- (void)pop_animationDidApply:(POPAnimation *)anim
{
NSValue *toValue = (NSValue *)[anim valueForKeyPath:@"currentValue"];
CGSize size = [toValue CGSizeValue];

_circleShape1.strokeEnd = (size.height - calculateConstant(0, 1, 1, 0.7))/calculateSlope(0, 1, 1, 0.7);

_circleShape2.strokeEnd = (size.height - calculateConstant(0, 1, 1, 0.7))/calculateSlope(0, 1, 1, 0.7);
}

CGFloat calculateSlope(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2)
{
return (y2 - y1) / (x2 - x1);
}

CGFloat calculateConstant(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2)
{
return (y1*(x2 - x1) - x1*(y2 - y1)) / (x2 - x1);
}

@end

几个非常核心的地方:

按钮的3个交互用状态一个都不能少哦:

需要实现动画的代理获取按钮的实时尺寸的信息,最为关键的一步哦:

计算一元一次方程:

POP动画[2],布布扣,bubuko.com

时间: 2024-12-10 00:48:09

POP动画[2]的相关文章

POP动画引擎中Layer与CALayer的一点区别

POP动画引擎是facebook提供的一个开源框架, 可以实现很多的动画效果, 这里就不一一介绍啦, 有兴趣的童鞋请移步: https://github.com/facebook/pop 下面简单的讲一下POP动画引擎中Layer与CALayer的区别: 这里, 代码做的都是同一个效果: 执行位移动画3秒, 然后在1秒后移除所有动画 使用POP效果图: 使用CALayer效果图: 可以看到, POP执行的动画当动画被移除之后, 被执行对象保留了被停止时的状态 而CALayer执行的动画当动画被移

自定义UINavigationController push和pop动画

http://segmentfault.com/q/1010000000143983 默认的UINavigationController push和pop的默认动画都是左右滑动推出,我的应用要求这种界面切换的动画效果复杂一点,大概有这么几个: 更快的左右推出,默认是0.3秒,我需要快一倍 带抖动的左右推出 水平翻转 纸张翻页效果 但是这些切换都要放在NavigationController里做管理,怎么实现,求个思路 ios 链接 评论 更多 默认排序时间排序 3 个回答 答案对人有帮助,有参考

POP动画[1]

POP动画[1] pop动画是facebook扩展CoreAnimation的,使用及其方便:) 1:Spring系列的弹簧效果(两个动画kPOPLayerBounds与kPOPLayerCornerRadius同时运行) #import "RootViewController.h" #import "YXEasing.h" #import "POP.h" #import "YXGCD.h" @interface RootVi

swift详解之二十七------------自定义UINavigationController的push和pop动画

自定义UINavigationController的push和pop动画 我们这里先创建一个简单的工程 , 在storyboard 中拖一个导航控制器 , rootViewController 改成我们的ViewController . 为了实现自定义动画切换 , 我们需要实现两个协议 . UIViewControllerAnimatedTransitioning,UINavigationControllerDelegate UIViewControllerAnimatedTransitioni

Facebook POP动画简单使用

简单实用POP动画 发现POP比较好的一点是保留了动画结束后的状态,通过block回调.使用POPAnimatableProperty 可以快速添加基本动画,也可以自定义属性动画. 弹性动画 - (void)spring{ POPSpringAnimation* framePOP = [POPSpringAnimation animationWithPropertyNamed:kPOPViewBackgroundColor]; framePOP.springSpeed = 10.f; frame

POP动画[3]

这一节主要讲解POP动画的自定义动画属性. POP动画中有一个参数,叫timingFunction,与CoreAnimation中的一个参数CAMediaTimingFunction基本一样,下图表示的是kCAMediaTimingFunctionEaseInEaseOut的曲线图. 下图是Spring动画效果: 我们可以使用自定义的属性来实现POP的库中没有提供的动画. 实现的效果: 源码: // // RootViewController.m // YXPOP // // Copyright

用POP动画引擎实现弹簧动画(POPSpringAnimation)

效果图: #import "ViewController.h" #import <POP.h> @interface ViewController () @property (nonatomic, weak) UIView *testView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor

pop动画

#import "ViewController.h" #import "POP.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selecto

用POP动画模拟真实秒钟摆动效果

静态图: 动画图: 此处用到了POP中的Spring系列动画,现提供源码如下: SecondClockView.h 与 SecondClockView.m // // SecondClockView.h // YouXianMingClock // // Created by YouXianMing on 14-10-12. // Copyright (c) 2014年 YouXianMing. All rights reserved. // #import <UIKit/UIKit.h> @