123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- //
- // Converted to Swift 4 by Swiftify v4.2.29618 - https://objectivec2swift.com/
- //
- // IndefiniteAnimatedView.swift
- // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
- //
- // Original Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved.
- // Modified Copyright © 2018 Ibrahim Hassan. All rights reserved.
- //
- import UIKit
- class IndefiniteAnimatedView : UIView {
-
- private var activityIndicator : UIActivityIndicatorView?
- private var strokeThickness : CGFloat?
- private var strokeColor : UIColor?
- private var indefinteAnimatedLayer : CAShapeLayer?
- private var radius : CGFloat?
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- if self.superview != nil {
- layoutAnimatedLayer()
- }
- }
-
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- }
- //MARK: - Setter Functions
- extension IndefiniteAnimatedView {
-
- func setIndefinite(radius: CGFloat) {
- if (self.radius != radius) {
- self.radius = radius
-
- self.getIndefinteAnimatedLayer().removeFromSuperlayer()
- self.indefinteAnimatedLayer = nil
-
- if superview != nil {
- layoutAnimatedLayer()
- }
- }
- }
-
- func setIndefinite(strokeThickness : CGFloat) {
- self.strokeThickness = strokeThickness
- if let strkthickness = self.strokeThickness {
- getIndefinteAnimatedLayer().lineWidth = strkthickness
- }
- }
-
- func setIndefinite(strokeColor: UIColor) {
- self.strokeColor = strokeColor
- getIndefinteAnimatedLayer().strokeColor = strokeColor.cgColor
- }
-
- }
- //MARK: - Getter Functions
- extension IndefiniteAnimatedView {
- private func getIndefinteAnimatedLayer() -> CAShapeLayer {
- if self.indefinteAnimatedLayer != nil {
- return self.indefinteAnimatedLayer!
- } else {
- let localRingRadius : CGFloat = radius ?? 18
- let localStrokeThickness : CGFloat = strokeThickness ?? 2
- let localStrokeColor : UIColor = strokeColor ?? UIColor.black
-
- let arcCenter = CGPoint(x: localRingRadius + localStrokeThickness / 2 + 5, y: localRingRadius + localStrokeThickness / 2 + 5)
- let smoothedPath = UIBezierPath(arcCenter: arcCenter, radius: localRingRadius, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi + CGFloat.pi / 2, clockwise: true)
-
- indefinteAnimatedLayer = CAShapeLayer()
- indefinteAnimatedLayer?.contentsScale = UIScreen.main.scale
- indefinteAnimatedLayer?.frame = CGRect.init(x: 0, y: 0, width: arcCenter.x * 2, height: arcCenter.y * 2)
- indefinteAnimatedLayer?.fillColor = UIColor.clear.cgColor
- indefinteAnimatedLayer?.strokeColor = localStrokeColor.cgColor
- indefinteAnimatedLayer?.lineWidth = localStrokeThickness
- indefinteAnimatedLayer?.lineCap = CAShapeLayerLineCap.round
- indefinteAnimatedLayer?.lineJoin = CAShapeLayerLineJoin.bevel
- indefinteAnimatedLayer?.path = smoothedPath.cgPath
-
- let maskLayer = CALayer()
- let image = loadImageBundle(named: "angle-mask")!
- maskLayer.contents = image.cgImage
- maskLayer.frame = indefinteAnimatedLayer!.bounds
- indefinteAnimatedLayer?.mask = maskLayer
-
- let animationDuration = TimeInterval.init(1)
- let linearCurve = CAMediaTimingFunction.init(name: .linear)
- let animation = CABasicAnimation.init(keyPath: "transform.rotation")
- animation.fromValue = 0
- animation.toValue = CGFloat.pi * 2
- animation.duration = animationDuration
- animation.timingFunction = linearCurve
- animation.isRemovedOnCompletion = false
- animation.repeatCount = .infinity
- animation.fillMode = .forwards
- animation.autoreverses = false
- indefinteAnimatedLayer?.mask?.add(animation, forKey: "rotate")
-
-
- let animationGroup = CAAnimationGroup.init()
- animationGroup.duration = animationDuration
- animationGroup.repeatCount = .infinity
- animationGroup.isRemovedOnCompletion = false
- animationGroup.timingFunction = linearCurve
-
- let strokeStartAnimation = CABasicAnimation.init(keyPath: "strokeStart")
- strokeStartAnimation.duration = animationDuration
- strokeStartAnimation.fromValue = 0.015
- strokeStartAnimation.toValue = 0.0001
-
- animationGroup.animations = [strokeStartAnimation]
- indefinteAnimatedLayer?.add(animationGroup, forKey: "progress")
- }
- return self.indefinteAnimatedLayer!
- }
- }
- //MARK: - ActivityIndicatorView Functions
- extension IndefiniteAnimatedView {
-
- func removeAnimationLayer() {
- for view in self.subviews {
- if let activityView = view as? UIActivityIndicatorView {
- activityView.removeFromSuperview()
- }
- }
- getIndefinteAnimatedLayer().removeFromSuperlayer()
- }
-
- func startAnimation() {
- if let activityIndicator = activityIndicator {
- self.addSubview(activityIndicator)
- activityIndicator.frame = CGRect.init(x: 8, y: 8, width: self.frame.size.width - 16, height: self.frame.size.height - 16)
- }
- }
-
- func stopActivityIndicator() {
- activityIndicator?.stopAnimating()
- }
-
- func setActivityIndicator(color: UIColor) {
- activityIndicator = UIActivityIndicatorView.init(style: .whiteLarge)
- activityIndicator?.hidesWhenStopped = true
- activityIndicator?.startAnimating()
- activityIndicator?.color = color
- }
- }
- //MARK: -
- extension IndefiniteAnimatedView {
- override func willMove(toSuperview newSuperview: UIView?) {
- if let _ = newSuperview {
- layoutAnimatedLayer()
- } else {
- getIndefinteAnimatedLayer().removeFromSuperlayer()
- indefinteAnimatedLayer = nil
- }
- }
-
- private func layoutAnimatedLayer() {
- let calayer = getIndefinteAnimatedLayer()
- self.layer.addSublayer(calayer)
- let widthDiff: CGFloat = bounds.width - layer.bounds.width
- let heightDiff: CGFloat = bounds.height - layer.bounds.height
- let xPos = bounds.width - layer.bounds.width / 2 - widthDiff / 2
- let yPos = bounds.height - layer.bounds.height / 2 - heightDiff / 2
- calayer.position = CGPoint.init(x: xPos, y: yPos)
- }
-
- override func sizeThatFits(_ size: CGSize) -> CGSize {
- let localRadius : CGFloat = radius ?? 18
- let localStrokeThickness : CGFloat = strokeThickness ?? 2
- for view in self.subviews {
- if let _ = view as? UIActivityIndicatorView {
- return CGSize.init(width: 50, height: 50)
- }
- }
- return CGSize.init(width: (localRadius + localStrokeThickness / 2 + 5) * 2, height: (localRadius + localStrokeThickness / 2 + 5) * 2)
- }
-
- private func loadImageBundle(named imageName:String) -> UIImage? {
- #if SWIFT_PACKAGE
- var imageBundle = Bundle.init(for: IHProgressHUD.self)
- if let resourcePath = Bundle.module.path(forResource: "IHProgressHUD", ofType: "bundle") {
- if let resourcesBundle = Bundle(path: resourcePath) {
- imageBundle = resourcesBundle
- }
- }
- return UIImage(named: imageName, in: imageBundle, compatibleWith: nil)
-
- #else
- var imageBundle = Bundle.init(for: IHProgressHUD.self)
- if let resourcePath = imageBundle.path(forResource: "IHProgressHUD", ofType: "bundle") {
- if let resourcesBundle = Bundle(path: resourcePath) {
- imageBundle = resourcesBundle
- }
- }
- return (UIImage(named: imageName, in: imageBundle, compatibleWith: nil))
- #endif
- }
- }
|