概要:
很多時候睦霎,我們都可以看到一些應用,會在加載數(shù)據時踏拜,顯示一個好看的占位動畫。那么這個好看的占位動畫是咋樣實現(xiàn)的呢低剔,這里給出了我自己的方案速梗,僅供學習探討。
先看效果圖
實現(xiàn)思路
一襟齿、首先我們根據設計圖布局視圖姻锁,為view(cell)中的每一個子空間設置約束,特別注意的是控件的寬度是必須限制的(給固定值或左右約束)猜欺;
二位隶、再為剛才視圖中的每一個子控件覆蓋一層弱網視圖view(這里稱它windlessView),并為windlessView添加動畫开皿,效果如圖涧黄;這一步我直接為UIView添加了一個擴展方法,凡是繼承view的都可調用赋荆;
三笋妥、在下拉加載數(shù)據之前,我們已經把一屏幕的view(cell)都創(chuàng)建好并顯示(即帶弱網效果的視圖)窄潭,當我們的數(shù)據返回時春宣,重新刷新界面,并移除windlessView嫉你。
注意:
在我的項目中使用的是MVVM框架月帝,所以我在ViewModel中添加了一個isWindless的屬性,加載數(shù)據時幽污,默認為true顯示弱網效果嚷辅,當數(shù)據成功返回時,值設為false距误,移除windlessView潦蝇。
弱網狀態(tài)禁止交互款熬。
添加弱網效果的核心代碼如下:
為當前view添加弱網視圖和動畫
import UIKit
let kWindlessViewTag = 91997
extension UIView {
/// 為視圖添加弱網效果
///
/// - Parameter isWindless: 是否為弱網狀態(tài)
func windless(isWindless: Bool) {
var windLessView: UIView? = self.viewWithTag(kWindlessViewTag)
if isWindless {
if windLessView == nil {
// 添加弱網視圖
windLessView = UIView(frame: self.bounds)
windLessView!.backgroundColor = UIColor(red: 247.0/255.0, green: 247.0/255.0, blue: 247.0/255.0, alpha: 1.0)
windLessView?.layer.position = CGPoint(x: 0, y: 0)
windLessView?.layer.anchorPoint = CGPoint(x: 0, y: 0)
windLessView!.tag = kWindlessViewTag
self.addSubview(windLessView!)
}
// 添加動畫
let random = CGFloat(self.randomNum(start: 4, end: 6)) / 10.0
let minW = self.bounds.size.width * random
let maxW = self.bounds.size.width * 1.0
let animation = CABasicAnimation(keyPath: "bounds.size.width")
animation.duration = 1
animation.repeatCount = MAXFLOAT
animation.autoreverses = true
animation.fromValue = CGFloat(minW)
animation.toValue = CGFloat(maxW)
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
windLessView!.layer.add(animation, forKey: "WindlessAnimation")
} else {
guard windLessView != nil else {
return
}
// 移除弱網視圖
windLessView?.removeFromSuperview()
}
}
/// 獲取(start~end)的隨機數(shù)(為了讓動畫更好看)
func randomNum(start: Int, end: Int) -> Int {
var temp = Int(arc4random_uniform(UInt32(end))) + 1
if temp < start {
temp = self.randomNum(start: start, end: end)
}
return temp
}
}
案例:
下面是我重寫setupContent為基類方法攘乒,刷新某個cell的數(shù)據贤牛,cell的顯示樣式根據ViewModel的具體值來展示。
override func setupContent<T>(model: T) where T: HomeResearchInfoViewModel {
updateContenView(isWindless: model.isWindless)
isUserInteractionEnabled = !model.isWindless
guard !model.isWindless else {
return
}
// TODO: 根據數(shù)據更新視圖则酝。殉簸。。
}
func updateContenView(isWindless: Bool) {
titleLabel.windless(isWindless: isWindless)
detailLabel.windless(isWindless: isWindless)
}
最后來一張完整的效果圖
這里沒有再提供demo沽讹。