iOS核心动画详解(CABasicAnimation)
前言
上一篇已经介绍了核心动画在UI渲染中的位置和基本概念,但是没有具体介绍CAAnimation子类的用法,本文将介绍CABasicAnimation及其子类CASpringAnimation的用法和一些注意事项。
一、CABasicAnimation
1.什么是CABasicAnimation
CABasicAnimation是核心动画类簇中的一个类,其父类是CAPropertyAnimation,其子类是CASpringAnimation,它的祖父是CAAnimation。它主要用于制作比较单一的动画,例如,平移、缩放、旋转、颜色渐变、边框的值的变化等,也就是将layer的某个属性值从一个值到另一个值的变化。类似x -> y这种变化,然而对于x -> y -> z甚至更多的变化是不行的。
2.常用属性
@property(nullable, strong) id fromValue;
@property(nullable, strong) id toValue;
@property(nullable, strong) id byValue;
很明显,fromvalue表示初始状态,tovalue表示最终状态,byvalue是在fromvalue的基础上发生的变化,这个可以慢慢测试,主要还是from和to。
3.实例化方法
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
下面是对keypath比较全面的总结,每个keypath对应一种属性值的变化,其中涉及到颜色变化的都必须使用CGColor,因为对应是对layer的属性。
#ifndef AnimationKeyPathName_h
#define AnimationKeyPathName_h
#import <Foundation/Foundation.h>
/* CATransform3D Key Paths */
/* 旋转x,y,z分别是绕x,y,z轴旋转 */
static NSString *kCARotation = @"transform.rotation";
static NSString *kCARotationX = @"transform.rotation.x";
static NSString *kCARotationY = @"transform.rotation.y";
static NSString *kCARotationZ = @"transform.rotation.z"; /* 缩放x,y,z分别是对x,y,z方向进行缩放 */
static NSString *kCAScale = @"transform.scale";
static NSString *kCAScaleX = @"transform.scale.x";
static NSString *kCAScaleY = @"transform.scale.y";
static NSString *kCAScaleZ = @"transform.scale.z"; /* 平移x,y,z同上 */
static NSString *kCATranslation = @"transform.translation";
static NSString *kCATranslationX = @"transform.translation.x";
static NSString *kCATranslationY = @"transform.translation.y";
static NSString *kCATranslationZ = @"transform.translation.z"; /* 平面 */
/* CGPoint中心点改变位置,针对平面 */
static NSString *kCAPosition = @"position";
static NSString *kCAPositionX = @"position.x";
static NSString *kCAPositionY = @"position.y"; /* CGRect */
static NSString *kCABoundsSize = @"bounds.size";
static NSString *kCABoundsSizeW = @"bounds.size.width";
static NSString *kCABoundsSizeH = @"bounds.size.height";
static NSString *kCABoundsOriginX = @"bounds.origin.x";
static NSString *kCABoundsOriginY = @"bounds.origin.y"; /* 透明度 */
static NSString *kCAOpacity = @"opacity";
/* 背景色 */
static NSString *kCABackgroundColor = @"backgroundColor";
/* 圆角 */
static NSString *kCACornerRadius = @"cornerRadius";
/* 边框 */
static NSString *kCABorderWidth = @"borderWidth";
/* 阴影颜色 */
static NSString *kCAShadowColor = @"shadowColor";
/* 偏移量CGSize */
static NSString *kCAShadowOffset = @"shadowOffset";
/* 阴影透明度 */
static NSString *kCAShadowOpacity = @"shadowOpacity";
/* 阴影圆角 */
static NSString *kCAShadowRadius = @"shadowRadius";
#endif /* AnimationKeyPathName_h */
4.简单用法
下面的类是用来测试不同keypath对应的动画,有些省略了,因为原理都是一样的。
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#import "BaseAnimationView.h" @interface BaseAnimationView()<UITableViewDelegate,UITableViewDataSource>
@property (nonatomic, strong) UIView *squareView;
@property (nonatomic, strong) UILabel *squareLabel;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *dataSource;
@end @implementation BaseAnimationView - (instancetype)init{
if (self = [super initWithFrame:CGRectMake(, , SCREEN_WIDTH, SCREEN_HEIGHT)]) {
[self initData];
[self setupUI];
}
return self;
}
- (void)setupUI{
self.squareView = [[UIView alloc] initWithFrame:CGRectMake(, , , )];
self.squareView.backgroundColor = [UIColor cyanColor];
self.squareView.layer.borderColor = [UIColor redColor].CGColor;
self.squareView.center = CGPointMake(SCREEN_WIDTH/2.0, );
self.squareView.layer.shadowOpacity = 0.6;
self.squareView.layer.shadowOffset = CGSizeMake(, );
self.squareView.layer.shadowRadius = ;
self.squareView.layer.shadowColor = [UIColor redColor].CGColor;
[self addSubview:self.squareView]; self.squareLabel = [[UILabel alloc] initWithFrame:self.squareView.bounds];
self.squareLabel.text = @"label";
self.squareLabel.textAlignment = NSTextAlignmentCenter;
self.squareLabel.textColor = [UIColor blackColor];
self.squareLabel.font = [UIFont systemFontOfSize:];
[self.squareView addSubview:self.squareLabel]; self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(, , SCREEN_WIDTH, SCREEN_HEIGHT-) style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self addSubview:self.tableView];
} - (CABasicAnimation *)getAnimationKeyPath:(NSString *)keyPath fromValue:(id)fromValue toValue:(id)toValue{
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:keyPath];
basicAnimation.fromValue = fromValue;
/*byvalue是在fromvalue的值的基础上增加量*/
//basicAnimation.byValue = @1;
basicAnimation.toValue = toValue;
basicAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];;
basicAnimation.duration = ;
basicAnimation.repeatCount = ;
/* animation remove from view after animation finish */
basicAnimation.removedOnCompletion = YES;
return basicAnimation;
}
- (void)initData{
/*
kCAScaleZ 缩放z 没有意义,因为是平面图形
kCAPositionX设置y没有意义,可以随意设置,同理kCAPositionY设置x没有意义
kCABackgroundColor,颜色变化必须要用CGColor
用到shadow的几个属性变化的时候,需要先设置shadow
*/
NSValue *startPoint = [NSValue valueWithCGPoint:self.squareView.center];
NSValue *endPoint = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue *shadowStartPoint = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue *shadowEndPoint = [NSValue valueWithCGPoint:CGPointMake(, )];
id startColor = (id)([UIColor cyanColor].CGColor);
id endColor = (id)([UIColor redColor].CGColor);
id shadowStartColor = (id)[UIColor clearColor].CGColor;
id shadowEndColor = (id)[UIColor redColor].CGColor;
self.dataSource = [NSMutableArray array];
NSArray *keypaths = @[kCARotation,kCARotationX,kCARotationY,kCARotationZ,
kCAScale,kCAScaleX,kCAScaleZ,kCAPositionX,
kCABoundsSizeW,kCAOpacity,kCABackgroundColor,kCACornerRadius,
kCABorderWidth,kCAShadowColor,kCAShadowRadius,kCAShadowOffset]; NSArray *fromValues = @[@,@,@,@,
@,@,@,startPoint,
@,@,startColor,@,
@,shadowStartColor,@,shadowStartPoint]; NSArray *toValues = @[@(M_PI),@(M_PI),@(M_PI),@(M_PI),
@,@,@,endPoint,
@,@,endColor,@,
@,shadowEndColor,@,shadowEndPoint];
for (int i=; i<keypaths.count; i++) {
AnimationModel *model = [[AnimationModel alloc] init];
model.keyPaths = keypaths[i];
model.fromValue = fromValues[i];
model.toValue = toValues[i];
[self.dataSource addObject:model];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.dataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
AnimationModel *model = [self.dataSource objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellID"];
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellID"];
}
cell.textLabel.text = model.keyPaths;
cell.selectionStyle = ;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
AnimationModel *model = [self.dataSource objectAtIndex:indexPath.row];
CABasicAnimation *animation = [self getAnimationKeyPath:model.keyPaths fromValue:model.fromValue toValue:model.toValue];
[self.squareView.layer addAnimation:animation forKey:nil];
}
@end
之所以在执行动画的view上加入一个label,是为了测试当layer放大时其子类的变化。layer进行缩放时,它的大小并没有发生改变,我们看到它变大或变小是因为它离我们的距离在发生改变,所以其子视图会随着一起变化。然而,改变其frame,它的大小和坐标是确实发生了改变,其子视图正常情况下是不会发生变化的。CABasicAnimation用法非常简单,下面介绍其子类CASpringAnimation。
二、CASpringAnimation
1.什么是CASpringAnimation
CASpringAnimation是在CABasicAnimation的基础上衍生的另一个动画类,它比CABasicAnimation多了动画的弹性,是动画不再是从一个状态变成另一个状态时显得生硬。CASpringAnimation是iOS9.0之后新加的。
2.新增属性
@property CGFloat mass; //质量(影响弹簧的惯性,质量越大,弹簧惯性越大,运动的幅度越大)
@property CGFloat stiffness; //弹性系数(弹性系数越大,弹簧的运动越快)
@property CGFloat damping; //阻尼系数(阻尼系数越大,弹簧的停止越快)
@property CGFloat initialVelocity; //初始速率(弹簧动画的初始速度大小,弹簧运动的初始方向与初始速率的正负一致,若初始速率为0,表示忽略该属性)
@property CGFloat settlingDuration; //结算时间(根据动画参数估算弹簧开始运动到停止的时间,动画设置的时间最好根据此时间来设置)
这三个属性可以设置动画在执行到最终状态后的弹性效果,具体值需要调试,下面给出一个具体的类来实现这一功能。
#import "SpringAnimationView.h"
#import "UIView+HPAdditions.h" @interface SpringAnimationView()<UITableViewDelegate,UITableViewDataSource>
@property (nonatomic, strong) UIView *squareView;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *dataSource;
@property (nonatomic, strong) UISlider *massSlider;
@property (nonatomic, strong) UISlider *stiffnessSlider;
@property (nonatomic, strong) UISlider *dampingSlider;
@property (nonatomic, strong) UILabel *massLabel;
@property (nonatomic, strong) UILabel *stiffnessLabel;
@property (nonatomic, strong) UILabel *dampingLabel;
@end @implementation SpringAnimationView - (instancetype)init{
if (self = [super initWithFrame:CGRectMake(, , SCREEN_WIDTH, SCREEN_HEIGHT)]) {
[self initData];
[self setupUI];
}
return self;
}
- (void)setupUI{
self.squareView = [[UIView alloc] initWithFrame:CGRectMake(, , , )];
self.squareView.backgroundColor = [UIColor cyanColor];
self.squareView.layer.borderColor = [UIColor redColor].CGColor;
self.squareView.center = CGPointMake(SCREEN_WIDTH/2.0, );
self.squareView.layer.shadowOpacity = 0.6;
self.squareView.layer.shadowOffset = CGSizeMake(, );
self.squareView.layer.shadowRadius = ;
self.squareView.layer.shadowColor = [UIColor redColor].CGColor;
[self addSubview:self.squareView]; self.massSlider = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
self.massSlider.minimumValue = ;
self.massSlider.maximumValue = ;
self.massSlider.tintColor = [UIColor cyanColor];
self.massSlider.thumbTintColor = [UIColor redColor];
self.massSlider.top = self.squareView.bottom + ;
[self addSubview:self.massSlider];
[self.massSlider addTarget:self action:@selector(durationChange:) forControlEvents:UIControlEventValueChanged]; self.stiffnessSlider = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
self.stiffnessSlider.minimumValue = ;
self.stiffnessSlider.maximumValue = ;
self.stiffnessSlider.tintColor = [UIColor cyanColor];
self.stiffnessSlider.thumbTintColor = [UIColor redColor];
self.stiffnessSlider.top = self.massSlider.bottom + ;
[self addSubview:self.stiffnessSlider];
[self.stiffnessSlider addTarget:self action:@selector(durationChange:) forControlEvents:UIControlEventValueChanged]; self.dampingSlider = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
self.dampingSlider.minimumValue = ;
self.dampingSlider.maximumValue = ;
self.dampingSlider.tintColor = [UIColor cyanColor];
self.dampingSlider.thumbTintColor = [UIColor redColor];
self.dampingSlider.top = self.stiffnessSlider.bottom + ;
[self addSubview:self.dampingSlider];
[self.dampingSlider addTarget:self action:@selector(durationChange:) forControlEvents:UIControlEventValueChanged]; self.massLabel = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
self.massLabel.text = @"mass";
self.massLabel.centerY = self.massSlider.centerY;
self.massLabel.left = self.massSlider.right+;
self.massLabel.textAlignment = NSTextAlignmentLeft;
self.massLabel.textColor = [UIColor blackColor];
self.massLabel.font = [UIFont systemFontOfSize:];
[self addSubview:self.massLabel]; self.stiffnessLabel = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
self.stiffnessLabel.text = @"stiffness";
self.stiffnessLabel.centerY = self.stiffnessSlider.centerY;
self.stiffnessLabel.left = self.stiffnessSlider.right+;
self.stiffnessLabel.textAlignment = NSTextAlignmentLeft;
self.stiffnessLabel.textColor = [UIColor blackColor];
self.stiffnessLabel.font = [UIFont systemFontOfSize:];
[self addSubview:self.stiffnessLabel]; self.dampingLabel = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
self.dampingLabel.text = @"damping";
self.dampingLabel.centerY = self.dampingSlider.centerY;
self.dampingLabel.left = self.dampingSlider.right+;
self.dampingLabel.textAlignment = NSTextAlignmentLeft;
self.dampingLabel.textColor = [UIColor blackColor];
self.dampingLabel.font = [UIFont systemFontOfSize:];
[self addSubview:self.dampingLabel]; self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(, self.dampingSlider.bottom+, SCREEN_WIDTH, SCREEN_HEIGHT-self.dampingSlider.bottom-) style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self addSubview:self.tableView];
} /* The mass of the object attached to the end of the spring. Must be greater
than 0. Defaults to one. */ //@property CGFloat mass; /* The spring stiffness coefficient. Must be greater than 0.
* Defaults to 100. */ //@property CGFloat stiffness; /* The damping coefficient. Must be greater than or equal to 0.
* Defaults to 10. */ //@property CGFloat damping; /* The initial velocity of the object attached to the spring. Defaults
* to zero, which represents an unmoving object. Negative values
* represent the object moving away from the spring attachment point,
* positive values represent the object moving towards the spring
* attachment point. */ //@property CGFloat initialVelocity; - (CASpringAnimation *)getAnimationKeyPath:(NSString *)keyPath fromValue:(id)fromValue toValue:(id)toValue{
CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:keyPath];
springAnimation.fromValue = fromValue;
springAnimation.toValue = toValue;
springAnimation.mass = self.massSlider.value;
springAnimation.stiffness = self.stiffnessSlider.value;
springAnimation.damping = self.dampingSlider.value;
springAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];;
springAnimation.duration = ;
springAnimation.repeatCount = ;
/* animation remove from view after animation finish */
springAnimation.removedOnCompletion = YES;
/*
只有当removedOnCompletion设置为no时,fillmode设置为kCAFillModeBoth或者kCAFillModeForwards才有效,
kCAFillModeRemoved //动画执行完成后回到初始状态
kCAFillModeBackwards //动画执行完成后回到初始状态
kCAFillModeForwards //动画执行完成后保留最后状态
kCAFillModeBoth //动画执行完成后保留最后状态
*/
springAnimation.fillMode = kCAFillModeForwards;
/*
动画执行完成后按原动画返回执行,default no
*/
// springAnimation.autoreverses = YES;
return springAnimation;
}
- (void)initData{
/*
kCAScaleZ 缩放z 没有意义,因为是平面图形
kCAPositionX设置y没有意义,可以随意设置,同理kCAPositionY设置x没有意义
kCABackgroundColor,颜色变化必须要用CGColor
用到shadow的几个属性变化的时候,需要先设置shadow
*/
NSValue *shadowStartPoint = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue *shadowEndPoint = [NSValue valueWithCGPoint:CGPointMake(, )];
id startColor = (id)([UIColor cyanColor].CGColor);
id endColor = (id)([UIColor redColor].CGColor);
id shadowStartColor = (id)[UIColor clearColor].CGColor;
id shadowEndColor = (id)[UIColor redColor].CGColor;
self.dataSource = [NSMutableArray array];
NSArray *keypaths = @[kCARotation,kCARotationX,kCARotationY,kCARotationZ,
kCAScale,kCAScaleX,kCAScaleZ,kCAPositionY,
kCABoundsSizeW,kCAOpacity,kCABackgroundColor,kCACornerRadius,
kCABorderWidth,kCAShadowColor,kCAShadowRadius,kCAShadowOffset]; NSArray *fromValues = @[@,@,@,@,
@,@,@,@,
@,@,startColor,@,
@,shadowStartColor,@,shadowStartPoint]; NSArray *toValues = @[@(M_PI),@(M_PI),@(M_PI),@(M_PI),
@,@,@,@,
@,@,endColor,@,
@,shadowEndColor,@,shadowEndPoint];
for (int i=; i<keypaths.count; i++) {
AnimationModel *model = [[AnimationModel alloc] init];
model.keyPaths = keypaths[i];
model.fromValue = fromValues[i];
model.toValue = toValues[i];
[self.dataSource addObject:model];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.dataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
AnimationModel *model = [self.dataSource objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellID"];
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellID"];
}
cell.textLabel.text = model.keyPaths;
cell.selectionStyle = ;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self.squareView.layer removeAllAnimations];
AnimationModel *model = [self.dataSource objectAtIndex:indexPath.row];
CABasicAnimation *animation = [self getAnimationKeyPath:model.keyPaths fromValue:model.fromValue toValue:model.toValue];
[self.squareView.layer addAnimation:animation forKey:@"animation"];
}
- (void)durationChange:(UISlider *)slider{
[slider setValue:slider.value];
if (slider==self.massSlider) {
self.massLabel.text = [NSString stringWithFormat:@"mass %.2f", slider.value];
}else if (slider==self.stiffnessSlider) {
self.stiffnessLabel.text = [NSString stringWithFormat:@"stiffness %.2f", slider.value];
}else if (slider==self.dampingSlider) {
self.dampingLabel.text = [NSString stringWithFormat:@"damping %.2f", slider.value];
}
}
@end --------------------------------------------------------------------------------------
#import <UIKit/UIKit.h> @interface UIView (HPAdditions)
@property (nonatomic) CGFloat top;
@property (nonatomic) CGFloat bottom;
@property (nonatomic) CGFloat left;
@property (nonatomic) CGFloat right; @property (nonatomic) CGFloat width;
@property (nonatomic) CGFloat height;
@property (nonatomic) CGPoint origin;
@property (nonatomic) CGSize size; @property (nonatomic) CGFloat centerX;
@property (nonatomic) CGFloat centerY; @end #import "UIView+HPAdditions.h" @implementation UIView (HPAdditions)
- (CGFloat)top{
return self.frame.origin.y;
}
- (void)setTop:(CGFloat)top{
CGRect frame = self.frame;
frame.origin.y = top;
self.frame = frame;
}
- (CGFloat)bottom{
return self.frame.origin.y+self.frame.size.height;
}
- (void)setBottom:(CGFloat)bottom{
CGRect frame = self.frame;
frame.origin.y = bottom-frame.size.height;
self.frame = frame;
}
- (CGFloat)left{
return self.frame.origin.x;
}
- (void)setLeft:(CGFloat)left{
CGRect frame = self.frame;
frame.origin.x = left;
self.frame = frame;
}
- (CGFloat)right{
return self.frame.origin.x+self.frame.size.width;
}
- (void)setRight:(CGFloat)right{
CGRect frame = self.frame;
frame.origin.x = right-frame.size.width;
self.frame = frame;
} - (CGFloat)width{
return self.frame.size.width;
}
- (void)setWidth:(CGFloat)width{
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
- (CGFloat)height{
return self.frame.size.height;
}
- (void)setHeight:(CGFloat)height{
CGRect frame = self.frame;
frame.size.height = height;
self.frame = frame;
}
- (CGFloat)centerX{
return self.center.x;
}
- (void)setCenterX:(CGFloat)centerX{
self.center = CGPointMake(centerX, self.center.y);
}
- (CGFloat)centerY{
return self.center.y;
}
- (void)setCenterY:(CGFloat)centerY{
self.center = CGPointMake(self.center.x, centerY);
}
- (CGPoint)origin{
return self.frame.origin;
}
- (void)setOrigin:(CGPoint)origin{
CGRect frame = self.frame;
frame.origin = origin;
self.frame = frame;
}
- (CGSize)size{
return self.frame.size;
}
- (void)setSize:(CGSize)size{
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
} @end
CABasicAnimation及其子类CASpringAnimation使用都是非常简单的,CASpringAnimation能够做出更加优雅的动画,建议使用。但是这两种动画能过制作的动画都是需要给定初始和最终状态值的,而中间过程需要系统去处理,这样的动画比较单一,下一篇将会介绍添加中间过程的动画CAKeyFrameAnimation关键帧动画,它能做出更加炫酷的动画。
iOS核心动画详解(CABasicAnimation)的更多相关文章
- iOS核心动画详解(一)
前言 这篇文章主要是针对核心动画(Core Animation)的讲解,不涉及UIView的动画.因为内容较多,这篇文章会分为几个章节来进行介绍.本文主要是介绍核心动画的几个类之间的关系和CAAnim ...
- iOS应用开发详解
<iOS应用开发详解> 基本信息 作者: 郭宏志 出版社:电子工业出版社 ISBN:9787121207075 上架时间:2013-6-28 出版日期:2013 年7月 开本:16开 ...
- iOS核心动画学习整理
最近利用业余时间终于把iOS核心动画高级技巧(https://zsisme.gitbooks.io/ios-/content/chapter1/the-layer-tree.html)看完,对应其中一 ...
- IOS 核心动画之CAKeyframeAnimation - iBaby
- IOS 核心动画之CAKeyframeAnimation - 简单介绍 是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation ...
- [转] ReactNative Animated动画详解
http://web.jobbole.com/84962/ 首页 所有文章 JavaScript HTML5 CSS 基础技术 前端职场 工具资源 更多频道▼ - 导航条 - 首页 所有文章 ...
- IOS 动画专题 --iOS核心动画
iOS开发系列--让你的应用“动”起来 --iOS核心动画 概览 通过核心动画创建基础动画.关键帧动画.动画组.转场动画,如何通过UIView的装饰方法对这些动画操作进行简化等.在今天的文章里您可以看 ...
- iOS开发:详解Objective-C runTime
Objective-C总Runtime的那点事儿(一)消息机制 最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎 ...
- iOS 核心动画 Core Animation浅谈
代码地址如下:http://www.demodashi.com/demo/11603.html 前记 关于实现一个iOS动画,如果简单的,我们可以直接调用UIView的代码块来实现,虽然使用UIVie ...
- iOS核心动画高级技巧之核心动画(三)
iOS核心动画高级技巧之CALayer(一) iOS核心动画高级技巧之图层变换和专用图层(二)iOS核心动画高级技巧之核心动画(三)iOS核心动画高级技巧之性能(四)iOS核心动画高级技巧之动画总结( ...
随机推荐
- 저장소system.runtime.remoting.messaging.callcontext
https://msdn.microsoft.com/ko-kr/library/system.runtime.remoting.messaging.callcontext(v=vs.110).asp ...
- Atitit.隔行换色 变色 css3 结构性伪类选择器
Atitit.隔行换色 变色 css3 结构性伪类选择器 1.1. css3隔行换色扩展阅读 1 1.2. 结构伪选择器 1 1.3. jQuery 选择器2 1.1. css3隔行换色扩展阅读 原 ...
- jsp的页面包含——静态包含、动态包含
一.静态包含:包含的文件可以是jsp文件.html文件.文本文件或者一段java代码.<%@ include file="要包含的文件路径"%> 实质是先将所包含的文件 ...
- CCNA2.0笔记_TCP/IP概述
主机到主机层(传输层) TCP与UDP UDP的特点 运行于 OSI 模型和 TCP/IP 模型的传输层 为应用程序提供网络层接入而无需为可靠性机制付出多余开销 属无连接协议 提供有限的错误检查 提供 ...
- Windows自带的端口转发工具netsh使用方法
微软Windows的netsh是一个命令行脚本实用工具.使用netsh工具 ,可以查看或更改本地计算机或远程计算机的网络配置.不仅可以在本地计算机上运行这些命令,而且可以在网络上的远程计算机上运行. ...
- 简单的异步Socket实现——SimpleSocket_V1.1
简单的异步Socket实现——SimpleSocket_V1.1 笔者在前段时间的博客中分享了一段简单的异步.net的Socket实现.由于是笔者自己测试使用的.写的很粗糙.很简陋.于是花了点时间自己 ...
- 【Python】Webpy 源码学习
那么webpy是什么呢? 阅读它的源码我们又能学到什么呢? 简单说webpy就是一个开源的web应用框架(官方首页:http://webpy.org/) 它的源代码非常整洁精干,学习它一方面可以让我们 ...
- redis info命令中各个参数的含义
Redis 性能调优相关笔记 2016年09月25日 15:42:04 WenCoding 阅读数:4844更多 个人分类: Redis数据库 info可以使用info [类别]输出指定类别内容i ...
- 参考 generate-parentheses
分析: 关键:当前位置左括号不少于右括号 图是什么? 节点:目前位置左括号和右括号数(x,y)(x>=y) 边:从(x,y)到(x+1,y)和(x,y+1) ...
- python爬取网站数据保存使用的方法
这篇文章主要介绍了使用Python从网上爬取特定属性数据保存的方法,其中解决了编码问题和如何使用正则匹配数据的方法,详情看下文 编码问题因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这 ...