美文网首页iOS Developer
iOS-CAShapeLayer实战

iOS-CAShapeLayer实战

作者: linbj | 来源:发表于2017-04-01 18:06 被阅读72次
    login.gif

    源代码

    项目的小动画基于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 <UIKit/UIKit.h>
    
    @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 <UIKit/UIKit.h>
    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
    
    

    相关文章

      网友评论

        本文标题:iOS-CAShapeLayer实战

        本文链接:https://www.haomeiwen.com/subject/xmziottx.html