美文网首页程序员效果
Swift4.0--弱网时,酷炫的占位动画实现思路详解

Swift4.0--弱网时,酷炫的占位动画实现思路详解

作者: 青苹果园 | 来源:发表于2018-04-11 16:40 被阅读111次
    loading.jpeg

    概要:

    很多时候,我们都可以看到一些应用,会在加载数据时,显示一个好看的占位动画。那么这个好看的占位动画是咋样实现的呢,这里给出了我自己的方案,仅供学习探讨。

    先看效果图

    windlessGif1

    实现思路

    一、首先我们根据设计图布局视图,为view(cell)中的每一个子空间设置约束,特别注意的是控件的宽度是必须限制的(给固定值或左右约束);

    二、再为刚才视图中的每一个子控件覆盖一层弱网视图view(这里称它windlessView),并为windlessView添加动画,效果如图;这一步我直接为UIView添加了一个扩展方法,凡是继承view的都可调用;

    三、在下拉加载数据之前,我们已经把一屏幕的view(cell)都创建好并显示(即带弱网效果的视图),当我们的数据返回时,重新刷新界面,并移除windlessView。

    注意:

    • 在我的项目中使用的是MVVM框架,所以我在ViewModel中添加了一个isWindless的属性,加载数据时,默认为true显示弱网效果,当数据成功返回时,值设为false,移除windlessView。

    • 弱网状态禁止交互。

    添加弱网效果的核心代码如下:

    为当前view添加弱网视图和动画

    import UIKit
    
    let kWindlessViewTag = 91997
    
    extension UIView {
        /// 为视图添加弱网效果
        ///
        /// - Parameter isWindless: 是否为弱网状态
        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)的随机数(为了让动画更好看)
        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的数据,cell的显示样式根据ViewModel的具体值来展示。

    override func setupContent<T>(model: T) where T: HomeResearchInfoViewModel {
            updateContenView(isWindless: model.isWindless)
            isUserInteractionEnabled = !model.isWindless
            guard !model.isWindless else {
                return
            }
            // TODO: 根据数据更新视图。。。
        }
    
        func updateContenView(isWindless: Bool) {
            titleLabel.windless(isWindless: isWindless)
            detailLabel.windless(isWindless: isWindless)
        }
    

    最后来一张完整的效果图

    windlessGif

    这里没有再提供demo。

    这是我的GitHub欢迎交流学习

    相关文章

      网友评论

        本文标题:Swift4.0--弱网时,酷炫的占位动画实现思路详解

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