源代码
项目的小动画基于CAShapeLayer与CABasicAnimation。
将界面分为三个模块介绍
- 渐变的背景色
利用CAGradientLayer实现渐变背景色
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.view.bounds;
gradientLayer.colors = @[
(__bridge id)[UIColor purpleColor].CGColor,
(__bridge id)[UIColor redColor].CGColor,
(__bridge id)[UIColor blueColor].CGColor
];
gradientLayer.startPoint = CGPointMake(0.5, 0);
gradientLayer.endPoint = CGPointMake(0.5, 1);
gradientLayer.locations = @[@0.3,@0.7,@1];
[self.view.layer addSublayer:gradientLayer];
- 带动画的textfield
监听文字长度的变化,利用animateWithDuration改变位置。
#import
@interface ICETextField : UIView
@property (nonatomic, strong) NSString *strPlaceHolder;
@property (nonatomic, strong) UITextField *tfdICE;
@end
//
// ICETextField.m
// ICELogin
//
// Created by iOS on 1/4/17.
// Copyright © 2017年 iOS. All rights reserved.
//
#import "ICETextField.h"
@interface ICETextField ()
<
UITextFieldDelegate
>
@property (nonatomic, strong) UILabel *lblPlaceHolder;
@property (nonatomic, assign) BOOL isUp;//yes表示placeholder在tfd上面
@end
@implementation ICETextField
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.isUp = NO;
[self createView];
}
return self;
}
- (void)setStrPlaceHolder:(NSString *)strPlaceHolder {
_strPlaceHolder = strPlaceHolder;
self.lblPlaceHolder.text = strPlaceHolder;
}
- (UITextField *)tfdICE {
if (!_tfdICE) {
_tfdICE = [[UITextField alloc]initWithFrame:CGRectZero];
_tfdICE.delegate = self;
[self addSubview:_tfdICE];
}
return _tfdICE;
}
- (UILabel *)lblPlaceHolder {
if (!_lblPlaceHolder) {
self.lblPlaceHolder = [[UILabel alloc]init];
self.lblPlaceHolder.textColor = [UIColor grayColor];
self.lblPlaceHolder.font = [UIFont systemFontOfSize:15];
_lblPlaceHolder.text = self.strPlaceHolder;
[self addSubview:self.lblPlaceHolder];
}
return _lblPlaceHolder;
}
- (void)createView {
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(p_TextFieldLengthChange:) name:UITextFieldTextDidChangeNotification object:self.tfdICE];
[self.lblPlaceHolder class];
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, CGRectGetHeight(self.frame)-1, CGRectGetWidth(self.frame), 1)];
view.backgroundColor = [UIColor whiteColor];
[self addSubview:view];
}
-(void)layoutSubviews {
[super layoutSubviews];
self.tfdICE.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)-1);
self.lblPlaceHolder.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)-1);
}
/**
监听tfd长度改变
@param sender sender
*/
- (void)p_TextFieldLengthChange:(UITextField *)sender {
[self p_movelblAnimation];
}
- (void)p_movelblAnimation {
if (_tfdICE.text.length == 0 && _isUp) {
//下移动
[self p_ChangeFrameWithBool:YES];
}
else if (_tfdICE.text.length != 0 && !_isUp) {
//上移动
[self p_ChangeFrameWithBool:NO];
}
}
- (void)p_ChangeFrameWithBool:(BOOL)isTurnDown {
NSLog(@"%@",NSStringFromCGPoint(self.lblPlaceHolder.center));
typeof(self) __weak weakSelf=self;
if (isTurnDown) {
//下移动
[UIView animateWithDuration:0.2 animations:^{
CGPoint point = weakSelf.lblPlaceHolder.center;
point.y = point.y + 20;
weakSelf.lblPlaceHolder.center = point;
weakSelf.isUp = NO;
}];
}
else {
//上移动
[UIView animateWithDuration:0.2 animations:^{
CGPoint point = weakSelf.lblPlaceHolder.center;
point.y = point.y - 20;
weakSelf.lblPlaceHolder.center = point;
weakSelf.isUp = YES;
}];
}
NSLog(@"%@",NSStringFromCGPoint(self.lblPlaceHolder.center));
}
@end
- 按钮的动画效果
#import
typedef void(^ICEBlock)();
@interface ICEButton : UIButton
@property (nonatomic,copy) ICEBlock translateBlock;
@end
//
// ICEButton.m
// ICELogin
//
// Created by iOS on 1/4/17.
// Copyright © 2017年 iOS. All rights reserved.
//
#import "ICEButton.h"
@interface ICEButton ()
@property (nonatomic, strong) UIButton *button;
//拉升透明的masklayer
@property (nonatomic,strong) CAShapeLayer *maskLayer;
//view底层的椭圆边框
@property (nonatomic,strong) CAShapeLayer *shapeLayer;
//loading layer
@property (nonatomic,strong) CAShapeLayer *loadingLayer;
//点击按钮后的layer
@property (nonatomic,strong) CAShapeLayer *clickCicrleLayer;
@end
@implementation ICEButton
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self drawMask:frame.size.height/2];
[self.layer addSublayer:self.maskLayer];
[self createDefaultBtn];
}
return self;
}
/**
画椭圆边框
@param height 高度
*/
- (void)drawMask:(CGFloat)height {
_shapeLayer = [CAShapeLayer layer];
_shapeLayer.frame = self.bounds;
_shapeLayer.path = [self drawBezierPath:height].CGPath;
_shapeLayer.fillColor = [UIColor clearColor].CGColor;
_shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
_shapeLayer.lineWidth = 2;
[self.layer addSublayer:_shapeLayer];
}
/**
创建按钮
*/
- (void) createDefaultBtn{
_button = [UIButton buttonWithType:UIButtonTypeCustom];
_button.frame = self.bounds;
_button.titleLabel.font = [UIFont systemFontOfSize:13.f];
[_button setTitle:@"登陆"
forState:UIControlStateNormal];
[_button setTitleColor:[UIColor whiteColor]
forState:UIControlStateNormal];
[self addSubview:_button];
[_button addTarget:self
action:@selector(didPressedToClickBtn:)
forControlEvents:UIControlEventTouchUpInside];
}
/**
点击按钮触发事件
@param sender sender
*/
- (void)didPressedToClickBtn:(UIButton *)sender {
//将要出现的盖在button上的layer
_maskLayer.opacity = 0.5;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 0.25;
animation.toValue = (__bridge id _Nullable)([self drawBezierPath:self.frame.size.height/2].CGPath);
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
[_maskLayer addAnimation:animation forKey:@"maskAnimation"];
[self performSelector:@selector(dismissAnimation) withObject:self afterDelay:animation.duration+0.2];
}
//登录按钮合拢并消失(透明)
-(void)dismissAnimation{
[self removeSubViews];
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
basicAnimation.duration = 0.2;
basicAnimation.toValue = (__bridge id _Nullable)([self drawBezierPath:self.frame.size.width/2].CGPath);
basicAnimation.removedOnCompletion = NO;
basicAnimation.fillMode = kCAFillModeForwards;
CABasicAnimation *basicAnimation1 = [CABasicAnimation animationWithKeyPath:@"opacity"];
basicAnimation1.beginTime = 0.10;
basicAnimation1.duration = 0.2;
basicAnimation1.toValue = @0;
basicAnimation1.fillMode = kCAFillModeForwards;
basicAnimation1.removedOnCompletion = NO;
animationGroup.removedOnCompletion = NO;
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.animations = @[
basicAnimation,
basicAnimation1
];
animationGroup.duration = basicAnimation1.beginTime + basicAnimation1.duration;
[_shapeLayer addAnimation:animationGroup forKey:@"dismissAnimation"];
[self performSelector:@selector(loadingAnimation) withObject:self afterDelay:animationGroup.duration];
}
//菊花
-(void)loadingAnimation{
CGFloat radius = self.bounds.size.height/2 - 3;
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath addArcWithCenter:CGPointMake(0,0) radius:radius startAngle:M_PI/2 endAngle:M_PI/2+M_PI/2 clockwise:YES];
_loadingLayer = [CAShapeLayer layer];
_loadingLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
_loadingLayer.fillColor = [UIColor clearColor].CGColor;
_loadingLayer.strokeColor = [UIColor whiteColor].CGColor;
_loadingLayer.lineWidth = 2;
_loadingLayer.path = bezierPath.CGPath;
[self.layer addSublayer:_loadingLayer];
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
basicAnimation.fromValue = @(0);
basicAnimation.toValue = @(M_PI*2);
basicAnimation.duration = 0.5;
basicAnimation.repeatCount = LONG_MAX;
[_loadingLayer addAnimation:basicAnimation forKey:@"loadingAnimation"];
[self performSelector:@selector(removeAllAnimation) withObject:self afterDelay:2];
}
//画一个位于view中间直径是view高的一个圆,透明度为0
-(CAShapeLayer *)maskLayer {
if(!_maskLayer){
_maskLayer = [CAShapeLayer layer];
_maskLayer.opacity = 0;
_maskLayer.fillColor = [UIColor whiteColor].CGColor;
_maskLayer.path = [self drawBezierPath:self.frame.size.width/2].CGPath;
}
return _maskLayer;
}
//
-(UIBezierPath *)drawBezierPath:(CGFloat)x{
CGFloat radius = self.bounds.size.height/2 - 3;
CGFloat right = self.bounds.size.width-x;
CGFloat left = x;
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
bezierPath.lineJoinStyle = kCGLineJoinRound;
bezierPath.lineCapStyle = kCGLineCapRound;
//右边圆弧
[bezierPath addArcWithCenter:CGPointMake(right, self.bounds.size.height/2) radius:radius startAngle:-M_PI/2 endAngle:M_PI/2 clockwise:YES];
//左边圆弧
[bezierPath addArcWithCenter:CGPointMake(left, self.bounds.size.height/2) radius:radius startAngle:M_PI/2 endAngle:-M_PI/2 clockwise:YES];
//闭合弧线
[bezierPath closePath];
return bezierPath;
}
/**
移除按钮 layer
*/
-(void)removeSubViews{
[_button removeFromSuperview];
[_maskLayer removeFromSuperlayer];
[_loadingLayer removeFromSuperlayer];
[_clickCicrleLayer removeFromSuperlayer];
}
-(void)removeAllAnimation{
[self removeSubViews];
if(self.translateBlock){
self.translateBlock();
}
}
@end