學會不同的Loading圖

前言:

愈來愈多的應用,在等待網絡時使用閃爍的效果,那麼這種效果,如何實現?且聽我娓娓道來,相關代碼已經放在githubgit

gif圖比效果偏快

本文概要

1、增長覆蓋層以及動態效果

一、獲取控件path

獲取每一個控件,而且求出控件的path(也就是控件最外邊的那些線),本來的控件遮罩只是矩形,爲了美觀,我建議每一個控件path添加圓角程序員

// 獲取每一個子控件的path,用於後面的加遮蓋 mask layer
    // 添加圓角
    UIBezierPath *defaultCoverblePath = [UIBezierPath bezierPathWithRoundedRect:subview.bounds cornerRadius:subview.frame.size.height/2.0/*subview.layer.cornerRadius*/];
    if ([subview isMemberOfClass:[UILabel class]] || [subview isMemberOfClass:[UITextView class]]) {
        defaultCoverblePath = [UIBezierPath bezierPathWithRoundedRect:subview.bounds cornerRadius:4];
    }
    UIBezierPath *relativePath = defaultCoverblePath;

    // 計算subview相對super的view的frame
    CGPoint offsetPoint = [subview convertRect:subview.bounds toView:view].origin; 
    [subview layoutIfNeeded];
    [relativePath applyTransform:CGAffineTransformMakeTranslation(offsetPoint.x, offsetPoint.y)];

    UIBezierPath *totalCoverablePath = [[UIBezierPath alloc] init];
    [totalCoverablePath appendPath:relativePath];
複製代碼

二、添加覆蓋層,僅顯示控件path的漸變色圖層

一、 添加覆蓋控件的覆蓋層github

二、 添加漸變色圖層到擋住控件的覆蓋層網絡

三、爲漸變色圖層設置mask,從而顯示mask面積下面的漸變色圖層(原理看下方)app

// 添加擋住全部控件的覆蓋層(擋住整superview,包括 superview 的子控件)
    self.viewCover.frame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height);
    [view addSubview:self.viewCover];

// gradientLayer CAGradientLayer是CALayer的一個子類,用來生成漸變色圖層
    CAGradientLayer *colorLayer = [CAGradientLayer layer];
    colorLayer.frame = (CGRect)self.view.bounds;

    colorLayer.startPoint = CGPointMake(-1.4, 0);
    colorLayer.endPoint = CGPointMake(1.4, 0);
    
    // 顏色分割線
    colorLayer.colors = @[(__bridge id)[UIColor colorWithRed:0 green:0 blue:0 alpha:0.03].CGColor,(__bridge id)[UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor,(__bridge id)[UIColor colorWithRed:1 green:1 blue:1 alpha:0.02].CGColor, (__bridge id)[UIColor colorWithRed:0 green:0 blue:0 alpha:0.06].CGColor, (__bridge id)[UIColor colorWithRed:0 green:0 blue:0 alpha:0.04].CGColor];

    colorLayer.locations = @[
                             [NSNumber numberWithDouble:colorLayer.startPoint.x],
                             [NSNumber numberWithDouble:colorLayer.startPoint.x],
                             @0,
                             [NSNumber numberWithDouble:0.2],
                             [NSNumber numberWithDouble:1.2]];

    [self.viewCover.layer addSublayer:colorLayer];
    
    // superview添加mask(能顯示的遮罩)
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.path = totalCoverablePath.CGPath;
    maskLayer.fillColor = [UIColor whiteColor].CGColor;
    colorLayer.mask = maskLayer;
複製代碼

原理:動畫

遮罩層必須至少有兩個圖層,上面的一個圖層爲「遮罩層」,下面的稱「被遮罩層」;這兩個圖層中只有相重疊的地方纔會被顯示。也就是說在遮罩層中有對象的地方就是「透明」的,能夠看到被遮罩層中的對象,而沒有對象的地方就是不透明的,被遮罩層中相應位置的對象是看不見的。 它的原理是:上面一層是遮罩層,下面一層是被遮罩層。遮罩層上的圖,本身是不顯示的。它只起到一個透光的做用。假定遮罩層上是一個正圓,那麼光線就會透過這個圓形,射到下面的被遮罩層上,只會顯示一個圓形的圖形。若是遮罩層上什麼都沒有,那麼光線就沒法透到下面來,那麼下面的被遮罩層什麼也顯示不出來。ui

上述代碼,得出以下效果: spa

上述效果,其實不少app就單純這樣使用了,可是咱們爲了更美化,決定爲其增長動態效果

三、爲漸變層增長動態效果

// 動畫 animate
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"locations"];
    animation.fromValue = colorLayer.locations;
    animation.toValue = @[
                          @0,
                          @1,
                          @1,
                          @1.2,
                          @1.2];
    animation.duration = 0.7;
    animation.repeatCount = HUGE;
    [animation setRemovedOnCompletion:NO];
    // 爲漸變層增長添加動畫
    [colorLayer addAnimation:animation forKey:@"locations-layer"];
複製代碼

2、移除全部覆蓋層以及效果

// 移除動態效果以及圖層
    [self.colorLayer removeAllAnimations];
    [self.colorLayer removeFromSuperlayer];
    [self.maskLayer removeFromSuperlayer];
    // 移除控件的覆蓋層
    [self.viewCover removeFromSuperview];
複製代碼

就這樣,完成了一個主流APP的Loding圖,我針對此代碼還進行了特殊封裝,代碼已經放在github code

demo圖




歡迎關注技術公衆號 「程序員大咖秀」orm

相關文章
相關標籤/搜索