學會不一樣的Loading圖

gif圖比效果偏快
前言:
越來越多的應用,在等待網路時使用閃爍的效果,那麼這種效果,如何實現?且聽我娓娓道來,相關程式碼已經放在 ofollow,noindex">github

本文概要
一、增加覆蓋層以及動態效果
1、獲取控制元件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(也就是控制元件最外邊的那些線),原本的控制元件遮罩只是矩形,為了美觀,我建議每個控制元件path新增圓角
2、新增覆蓋層,僅顯示控制元件path的漸變色圖層
// 新增擋住所有控制元件的覆蓋層(擋住整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;
1、 新增覆蓋控制元件的覆蓋層
2、 新增漸變色圖層到擋住控制元件的覆蓋層
3、為漸變色圖層設定mask,從而顯示mask面積下面的漸變色圖層(原理看下方)
原理:
遮罩層必須至少有兩個圖層,上面的一個圖層為“遮罩層”,下面的稱“被遮罩層”;這兩個圖層中只有相重疊的地方才會被顯示。也就是說在遮罩層中有物件的地方就是“透明”的,可以看到被遮罩層中的物件,而沒有物件的地方就是不透明的,被遮罩層中相應位置的物件是看不見的。
它的原理是:上面一層是遮罩層,下面一層是被遮罩層。遮罩層上的圖,自己是不顯示的。它只起到一個透光的作用。假定遮罩層上是一個正圓,那麼光線就會透過這個圓形,射到下面的被遮罩層上,只會顯示一個圓形的圖形。如果遮罩層上什麼都沒有,那麼光線就無法透到下面來,那麼下面的被遮罩層什麼也顯示不出來。
上述程式碼,得出如下效果:

上述效果,其實很多app就單純這樣使用了,但是我們為了更美化,決定為其增加動態效果
3、為漸變層增加動態效果
// 動畫 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"];
二、移除所有覆蓋層以及效果
// 移除動態效果以及圖層 [self.colorLayer removeAllAnimations]; [self.colorLayer removeFromSuperlayer]; [self.maskLayer removeFromSuperlayer]; // 移除控制元件的覆蓋層 [self.viewCover removeFromSuperview];
就這樣,完成了一個主流APP的Loding圖,我針對此程式碼還進行了特殊封裝,程式碼已經放在 github

demo圖