Skip to content

Instantly share code, notes, and snippets.

@AmatsuZero
Created October 16, 2018 11:30
Show Gist options
  • Save AmatsuZero/896effc8f5e424a3e8f1b1a0624665d3 to your computer and use it in GitHub Desktop.
Save AmatsuZero/896effc8f5e424a3e8f1b1a0624665d3 to your computer and use it in GitHub Desktop.
eShop Loading Effect
//
// 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