Created
October 16, 2018 11:30
-
-
Save AmatsuZero/896effc8f5e424a3e8f1b1a0624665d3 to your computer and use it in GitHub Desktop.
eShop Loading Effect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// EShopLoadingView.swift | |
// EShopHelper | |
// | |
// Created by Jiang,Zhenhua on 2018/10/16. | |
// Copyright © 2018 Daubert. All rights reserved. | |
// | |
import UIKit | |
class EShopLoadingView: UIView { | |
private let animationLayer = CALayer() | |
private let fixedHeight: CGFloat = 44 | |
private let duration: CFTimeInterval = 1 | |
private let label = UILabel() | |
var fillColor = UIColor(r: 255, g: 156, b: 99) { | |
didSet { | |
animationLayer.sublayers?.forEach { $0.backgroundColor = fillColor.cgColor } | |
} | |
} | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
backgroundColor = UIColor(r: 255, g: 120, b: 45) | |
layer.addSublayer(animationLayer) | |
label.font = UIFont.systemFont(ofSize: 27) | |
label.text = "eShop" | |
label.textColor = .white | |
label.textAlignment = .center | |
label.frame = .init(x: 0, y: 0, width: 79, height: 31.5) | |
addSubview(label) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func draw(_ rect: CGRect) { | |
super.draw(rect) | |
animationLayer.frame = .init(origin: .zero, size: rect.size) | |
let count = Int(rect.height / fixedHeight) | |
// frame发生变化,或者屏幕转向发生变化,则需要重绘 | |
if animationLayer.sublayers?.count ?? 0 != count || | |
animationLayer.frame.width != rect.width { | |
animationLayer.sublayers?.forEach { $0.removeFromSuperlayer() } | |
animationLayer.sublayers?.removeAll() | |
for (i, y) in stride(from: 0, through: rect.height, by: fixedHeight).enumerated() { | |
let bouncingLayer = CAShapeLayer() | |
bouncingLayer.backgroundColor = fillColor.cgColor | |
bouncingLayer.anchorPoint = .zero // 默认是在中间,这里需要设置为0.0 | |
bouncingLayer.frame = .init(x: 0, y: y, width: rect.width, height: fixedHeight) | |
let animation = CABasicAnimation(keyPath: "bounds.size.width") | |
animation.duration = duration | |
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) | |
animation.fromValue = 0 | |
animation.toValue = rect.width | |
animation.beginTime = CACurrentMediaTime() + CFTimeInterval(i) * (duration / Double(count)) | |
animation.fillMode = kCAFillModeBackwards | |
animation.repeatCount = .greatestFiniteMagnitude | |
animation.autoreverses = true | |
animation.delegate = self | |
bouncingLayer.add(animation, forKey: "bouncing_\(i)") | |
animationLayer.addSublayer(bouncingLayer) | |
} | |
} | |
label.frame.origin.x = rect.width - label.frame.width - 20 | |
label.frame.origin.y = rect.height - label.frame.height - 20 | |
} | |
} | |
extension EShopLoadingView: CAAnimationDelegate { | |
func animationDidStart(_ anim: CAAnimation) { | |
} | |
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment