From d979f65b80910906b7382b2976f1b044beeb896a Mon Sep 17 00:00:00 2001 From: Felix Mau Date: Thu, 18 Aug 2022 19:01:46 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20::=20Extract=20logic=20int?= =?UTF-8?q?o=20`SizeUpdate`=20struct?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GradientActivityIndicatorViewModel.swift | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/GradientLoadingBar/Feature/GradientActivityIndicatorView/GradientActivityIndicatorViewModel.swift b/GradientLoadingBar/Feature/GradientActivityIndicatorView/GradientActivityIndicatorViewModel.swift index ddf095c..3e82098 100644 --- a/GradientLoadingBar/Feature/GradientActivityIndicatorView/GradientActivityIndicatorViewModel.swift +++ b/GradientLoadingBar/Feature/GradientActivityIndicatorView/GradientActivityIndicatorViewModel.swift @@ -12,15 +12,6 @@ import LightweightObservable /// This view model contains all logic related to the `GradientActivityIndicatorView`. final class GradientActivityIndicatorViewModel { - // MARK: - Types - - /// - Note: The `fromValue` used on the `CABasicAnimation` is dependent on the `frame`, - /// therefore we always update these values together. - struct SizeUpdate: Equatable { - let frame: CGRect - let fromValue: CGFloat - } - // MARK: - Public properties /// Observable state of the progress animation. @@ -53,12 +44,7 @@ final class GradientActivityIndicatorViewModel { /// The bounds of the view. var bounds: CGRect = .zero { didSet { - // Three times of the width in order to apply normal, reversed and normal gradient - // to simulate an infinite animation. - var frame = bounds - frame.size.width *= 3 - - gradientLayerSizeUpdateSubject.value = SizeUpdate(frame: frame, fromValue: bounds.width * -2) + gradientLayerSizeUpdateSubject.value = SizeUpdate(bounds: bounds) } } @@ -82,7 +68,7 @@ final class GradientActivityIndicatorViewModel { // As a `UIView` is initially visible, we also have to start the progress animation initially. private let isAnimatingSubject = Variable(true) - private let gradientLayerSizeUpdateSubject = Variable(SizeUpdate(frame: .zero, fromValue: 0)) + private let gradientLayerSizeUpdateSubject = Variable(SizeUpdate(bounds: .zero)) private let gradientLayerColorsSubject: Variable<[CGColor]> private let gradientLayerAnimationDurationSubject: Variable @@ -116,6 +102,37 @@ final class GradientActivityIndicatorViewModel { } } +// MARK: - Supporting Types + +extension GradientActivityIndicatorViewModel { + + /// - Note: The `fromValue` used on the `CABasicAnimation` is dependent on the `frame`, + /// therefore we always update these values together. + struct SizeUpdate: Equatable { + + /// The frame of our gradient layer. + /// This has to be three times the width of the parent bounds in order to apply the normal, reversed and + /// again normal gradient colors to simulate the infinite animation. + var frame: CGRect { + var frame = bounds + frame.size.width *= 3 + + return frame + } + + var fromValue: CGFloat { + bounds.width * -2 + } + + /// The boundaries of the superview. + private let bounds: CGRect + + init(bounds: CGRect) { + self.bounds = bounds + } + } +} + // MARK: - Helper private extension Array where Element == UIColor {