码迷,mamicode.com
首页 > 编程语言 > 详细

POP的spring动画各个参数详解

时间:2015-05-14 23:38:47      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:

POP的spring动画各个参数详解

 技术分享

 

效果

技术分享

 

源码

https://github.com/YouXianMing/POPSpring

//
//  RangeValueView.h
//  POPSpring
//
//  Created by YouXianMing on 15/5/14.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface RangeValueView : UIView

/**
 *  文本标签
 */
@property (nonatomic, strong)   NSString  *text;

/**
 *  一些值的设置
 */
@property (nonatomic)           CGFloat    minValue;
@property (nonatomic)           CGFloat    maxValue;
@property (nonatomic, readonly) CGFloat    currentValue;
@property (nonatomic)           CGFloat    defaultValue;

/**
 *  便利构造器创建出视图
 *
 *  @param frame        控件的尺寸
 *  @param name         控件名字
 *  @param minValue     最小值
 *  @param maxValue     最大值
 *  @param defaultValue 默认值
 *
 *  @return 视图对象
 */
+ (instancetype)rangeValueViewWithFrame:(CGRect)frame
                                   name:(NSString *)name
                               minValue:(CGFloat)minValue
                               maxValue:(CGFloat)maxValue
                           defaultValue:(CGFloat)defaultValue;

@end
//
//  RangeValueView.m
//  POPSpring
//
//  Created by YouXianMing on 15/5/14.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import "RangeValueView.h"


#define    SLIDER_WIDTH    [UIScreen mainScreen].bounds.size.width



@interface RangeValueView ()

@property (nonatomic)          CGFloat    currentValue;

@property (nonatomic, strong)  UILabel   *labelName;
@property (nonatomic, strong)  UILabel   *labelValue;
@property (nonatomic, strong)  UISlider  *slider;

@end

@implementation RangeValueView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self initViews];
    }
    
    return self;
}

- (void)initViews {
    
    CGRect frame   = self.frame;
    CGFloat width  = frame.size.width;
    
    // 标签
    self.labelName               = [[UILabel alloc] initWithFrame:CGRectMake(3, 0, 100, 20)];
    self.labelName.font          = [UIFont fontWithName:@"AppleSDGothicNeo-Regular" size:12.f];
    [self addSubview:self.labelName];
    
    
    self.labelValue               = [[UILabel alloc] initWithFrame:CGRectMake(width - 103, 0, 100, 20)];
    self.labelValue.font          = [UIFont fontWithName:@"AppleSDGothicNeo-Regular" size:12.f];
    self.labelValue.textAlignment = NSTextAlignmentRight;
    [self addSubview:self.labelValue];
    
    
    // Slider
    self.slider = [[UISlider alloc] initWithFrame:CGRectMake(2, 15, width - 4, 10)];
    [self addSubview:self.slider];
    self.slider.minimumTrackTintColor = [[UIColor blackColor] colorWithAlphaComponent:0.1f];
    self.slider.maximumTrackTintColor = [[UIColor grayColor] colorWithAlphaComponent:0.05f];
    [self.slider setThumbImage:[UIImage imageNamed:@"slider"]
                      forState:UIControlStateNormal];
    [self.slider setThumbImage:[UIImage imageNamed:@"slider"]
                      forState:UIControlStateHighlighted];

    [self.slider addTarget:self
                    action:@selector(sliderChanged:)
          forControlEvents:UIControlEventValueChanged];
}


- (void)sliderChanged:(UISlider *)slider {
    // 更新UI
    CGFloat value        = slider.value;
    NSString *string     = [NSString stringWithFormat:@"%.2f", value];
    self.labelValue.text = string;
    
    // 当前的value值
    _currentValue        = value;
}


+ (instancetype)rangeValueViewWithFrame:(CGRect)frame
                                   name:(NSString *)name
                               minValue:(CGFloat)minValue
                               maxValue:(CGFloat)maxValue
                           defaultValue:(CGFloat)defaultValue {
    
    CGFloat x      = frame.origin.x;
    CGFloat y      = frame.origin.y;
    CGFloat width  = frame.size.width;
    CGFloat height = 25;
    
    RangeValueView *range = [[RangeValueView alloc] initWithFrame:CGRectMake(x, y, width, height)];
    
    // 基本配置
    range.maxValue        = maxValue;
    range.minValue        = minValue;
    range.defaultValue    = defaultValue;
    range.text            = name;
    
    // 额外配置
    range.currentValue    = defaultValue;
    range.labelValue.text = [NSString stringWithFormat:@"%.2f", defaultValue];
    
    return range;
}



@synthesize minValue = _minValue;
- (void)setMinValue:(CGFloat)minValue {
    _minValue            = minValue;
    _slider.minimumValue = minValue;
}
- (CGFloat)minValue {
    return _minValue;
}

@synthesize maxValue = _maxValue;
- (void)setMaxValue:(CGFloat)maxValue {
    _maxValue            = maxValue;
    _slider.maximumValue = maxValue;
}
- (CGFloat)maxValue {
    return _maxValue;
}

@synthesize defaultValue = _defaultValue;
- (void)setDefaultValue:(CGFloat)defaultValue {
    _defaultValue = defaultValue;
    _slider.value = defaultValue;
}
- (CGFloat)defaultValue {
    return _defaultValue;
}

@synthesize text = _text;
- (void)setText:(NSString *)text {
    _text           = text;
    _labelName.text = text;
}

- (NSString *)text {
    return _text;
}

@end
//
//  ViewController.m
//  POPSpring
//
//  Created by YouXianMing on 15/5/14.
//  Copyright (c) 2015年 YouXianMing. All rights reserved.
//

#import "ViewController.h"
#import "RangeValueView.h"
#import "POP.h"
#import "NSString+RichText.h"

@interface ViewController ()

@property (nonatomic, strong) UILabel  *secondsLabel;

@property (nonatomic, strong) UIButton *showView;
@property (nonatomic, strong) NSDate   *dateStart;

@property (nonatomic, strong) RangeValueView *rangeSpeed;
@property (nonatomic, strong) RangeValueView *rangeBounciness;
@property (nonatomic, strong) RangeValueView *rangeMass;
@property (nonatomic, strong) RangeValueView *rangeFriction;
@property (nonatomic, strong) RangeValueView *rangeTension;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    [self initSecondLabel];
    
    
    [self initButton];
    
    
    [self initRangeViews];
}

/**
 *  初始化显示秒钟的label
 */
- (void)initSecondLabel {
    self.secondsLabel                = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 20)];
    self.secondsLabel.attributedText = [self stringWithFloat:0.f];
    [self.view addSubview:self.secondsLabel];
}

/**
 *  创建富文本
 *
 *  @param value 输入的值
 *
 *  @return 返回创建好的富文本
 */
- (NSAttributedString *)stringWithFloat:(CGFloat)value {
    
    // 字符串
    NSString *stringValue  = [NSString stringWithFormat:@"%.2f", value];
    NSString *secondString = [NSString stringWithFormat:@"seconds"];
    NSString *totalString  = [NSString stringWithFormat:@"%@ %@", stringValue, secondString];
    
    // 字体
    UIFont *allFont        = [UIFont fontWithName:@"Avenir-Roman" size:14.f];
    UIFont *ValueFont      = [UIFont fontWithName:@"Avenir-Roman" size:16.f];
    
    // 配置富文本
    return [totalString createAttributedStringAndConfig:            @[
              [ConfigAttributedString font:allFont   range:[totalString range]],
              [ConfigAttributedString font:ValueFont range:[stringValue rangeFrom:totalString]],
              [ConfigAttributedString foregroundColor:[[UIColor grayColor] colorWithAlphaComponent:0.4f]
                                                range:[secondString rangeFrom:totalString]]
              ]];
}

/**
 *  初始化测试动画用的按钮
 */
- (void)initButton {
    
    CGFloat width                    = 100.f;
    self.showView                    = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, width, width)];
    self.showView.center             = CGPointMake(self.view.middleX, 175);
    self.showView.backgroundColor    = [UIColor cyanColor];
    self.showView.layer.cornerRadius = self.showView.width / 2.f;
    [self.view addSubview:self.showView];
    [self.showView addTarget:self
                      action:@selector(doAnimation)
            forControlEvents:UIControlEventTouchUpInside];
}

/**
 *  测试用rangeView
 */
- (void)initRangeViews {
    self.rangeSpeed = [RangeValueView rangeValueViewWithFrame:CGRectMake(10, Height - 60, Width - 20, 0)
                                                         name:@"速度  Speed"
                                                     minValue:0.f
                                                     maxValue:20.f
                                                 defaultValue:12.f];
    [self.view addSubview:self.rangeSpeed];
    
    
    self.rangeBounciness = [RangeValueView rangeValueViewWithFrame:CGRectMake(10, Height - 60 - 40, Width - 20, 0)
                                                              name:@"弹力  Bounciness"
                                                          minValue:0.f
                                                          maxValue:20.f
                                                      defaultValue:4.f];
    [self.view addSubview:self.rangeBounciness];
    
    
    self.rangeMass = [RangeValueView rangeValueViewWithFrame:CGRectMake(10, Height - 60 - 40*2, Width - 20, 0)
                                                        name:@"质量  Mass"
                                                    minValue:0.1
                                                    maxValue:10.f
                                                defaultValue:1.f];
    [self.view addSubview:self.rangeMass];
    
    
    self.rangeFriction = [RangeValueView rangeValueViewWithFrame:CGRectMake(10, Height - 60 - 40*3, Width - 20, 0)
                                                            name:@"摩擦  Friction"
                                                        minValue:1
                                                        maxValue:50
                                                    defaultValue:30.486980];
    [self.view addSubview:self.rangeFriction];
    
    
    self.rangeTension = [RangeValueView rangeValueViewWithFrame:CGRectMake(10, Height - 60 - 40*4, Width - 20, 0)
                                                           name:@"拉力  Tension"
                                                       minValue:1
                                                       maxValue:1000
                                                   defaultValue:300];
    [self.view addSubview:self.rangeTension];
}

/**
 *  执行动画操作
 */
- (void)doAnimation {
    
    // 移除动画
    [self.showView.layer pop_removeAllAnimations];
    
    POPSpringAnimation *spring = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY];
    
    // 设置代理
    spring.delegate            = self;
    
    // 动画起始值 + 动画结束值
    spring.fromValue           = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)];
    spring.toValue             = [NSValue valueWithCGSize:CGSizeMake(2.f, 2.f)];
    
    // 参数的设置
    spring.springSpeed         = self.rangeSpeed.currentValue;
    spring.springBounciness    = self.rangeBounciness.currentValue;
    spring.dynamicsMass        = self.rangeMass.currentValue;
    spring.dynamicsFriction    = self.rangeFriction.currentValue;
    spring.dynamicsTension     = self.rangeTension.currentValue;
    
    // 执行动画
    [self.showView.layer pop_addAnimation:spring forKey:nil];
}


#pragma mark - POP动画相关代理
- (void)pop_animationDidStart:(POPAnimation *)anim {
    self.dateStart = [NSDate date];
}

- (void)pop_animationDidApply:(POPAnimation *)anim {
    CGFloat seconds                  = -[self.dateStart timeIntervalSinceNow];
    self.secondsLabel.attributedText = [self stringWithFloat:seconds];
}

- (void)pop_animationDidStop:(POPAnimation *)anim finished:(BOOL)finished {
    CGFloat seconds                  = -[self.dateStart timeIntervalSinceNow];
    self.secondsLabel.attributedText = [self stringWithFloat:seconds];
}

@end

 

 

说明

1. POP动画中的Spring弹簧动画因为没办法计算出动画所需要的时间,所以,本人写了一个demo用以测试不同参数下的弹簧动画效果以及花费的时间.

2. 本人写了一个小控件RangeValueView,可以单独拿出来用,很方便.

技术分享

 

细节

技术分享

 

POP的spring动画各个参数详解

标签:

原文地址:http://www.cnblogs.com/YouXianMing/p/4503387.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!