Skip to content

Commit c7bcd73

Browse files
add currentValue to CircularProgressVM
1 parent 4a31807 commit c7bcd73

File tree

4 files changed

+51
-24
lines changed

4 files changed

+51
-24
lines changed

Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/CircularProgressPreview.swift

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@ import UIKit
44

55
struct CircularProgressPreview: View {
66
@State private var model = Self.initialModel
7-
@State private var currentValue: CGFloat = Self.initialValue
87

9-
private let circularProgress = UKCircularProgress(
10-
initialValue: Self.initialValue,
11-
model: Self.initialModel
12-
)
8+
private let circularProgress = UKCircularProgress(model: Self.initialModel)
139

1410
private let timer = Timer
1511
.publish(every: 0.5, on: .main, in: .common)
@@ -21,18 +17,14 @@ struct CircularProgressPreview: View {
2117
self.circularProgress
2218
.preview
2319
.onAppear {
24-
self.circularProgress.currentValue = Self.initialValue
2520
self.circularProgress.model = Self.initialModel
2621
}
2722
.onChange(of: model) { newModel in
2823
self.circularProgress.model = newModel
2924
}
30-
.onChange(of: self.currentValue) { newValue in
31-
self.circularProgress.currentValue = newValue
32-
}
3325
}
3426
PreviewWrapper(title: "SwiftUI") {
35-
SUCircularProgress(currentValue: self.currentValue, model: self.model)
27+
SUCircularProgress(model: self.model)
3628
}
3729
Form {
3830
ComponentColorPicker(selection: self.$model.color)
@@ -54,28 +46,25 @@ struct CircularProgressPreview: View {
5446
SizePicker(selection: self.$model.size)
5547
}
5648
.onReceive(self.timer) { _ in
57-
if self.currentValue < self.model.maxValue {
49+
if self.model.currentValue < self.model.maxValue {
5850
let step = (self.model.maxValue - self.model.minValue) / 100
59-
self.currentValue = min(
51+
self.model.currentValue = min(
6052
self.model.maxValue,
61-
self.currentValue + CGFloat(Int.random(in: 1...20)) * step
53+
self.model.currentValue + CGFloat(Int.random(in: 1...20)) * step
6254
)
6355
} else {
64-
self.currentValue = self.model.minValue
56+
self.model.currentValue = self.model.minValue
6557
}
66-
self.model.label = "\(Int(self.currentValue))%"
58+
self.model.label = "\(Int(self.model.currentValue))%"
6759
}
6860
}
6961
}
7062

7163
// MARK: - Helpers
7264

73-
private static var initialValue: Double {
74-
return 0.0
75-
}
76-
7765
private static var initialModel = CircularProgressVM {
7866
$0.label = "0%"
67+
$0.currentValue = 0.0
7968
}
8069
}
8170

Sources/ComponentsKit/Components/CircularProgress/Models/CircularProgressVM.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ public struct CircularProgressVM: ComponentVM {
77
/// Defaults to `.accent`.
88
public var color: ComponentColor = .accent
99

10+
/// The current value of the circular progress.
11+
///
12+
/// Defaults to `0`.
13+
public var currentValue: CGFloat = 0
14+
1015
/// The font used for the circular progress label text.
1116
public var font: UniversalFont?
1217

@@ -103,6 +108,13 @@ extension CircularProgressVM {
103108
}
104109

105110
extension CircularProgressVM {
111+
var progress: CGFloat {
112+
let range = self.maxValue - self.minValue
113+
guard range > 0 else { return 0 }
114+
let normalized = (self.currentValue - self.minValue) / range
115+
return max(0, min(1, normalized))
116+
}
117+
106118
func progress(for currentValue: CGFloat) -> CGFloat {
107119
let range = self.maxValue - self.minValue
108120
guard range > 0 else { return 0 }
@@ -123,6 +135,7 @@ extension CircularProgressVM {
123135
func shouldRecalculateProgress(_ oldModel: Self) -> Bool {
124136
return self.minValue != oldModel.minValue
125137
|| self.maxValue != oldModel.maxValue
138+
|| self.currentValue != oldModel.currentValue
126139
}
127140
func shouldUpdateShape(_ oldModel: Self) -> Bool {
128141
return self.shape != oldModel.shape

Sources/ComponentsKit/Components/CircularProgress/SUCircularProgress.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ public struct SUCircularProgress: View {
88
public var model: CircularProgressVM
99

1010
/// The current progress value.
11-
public var currentValue: CGFloat
11+
public var currentValue: CGFloat?
1212

1313
private var progress: CGFloat {
14-
self.model.progress(for: self.currentValue)
14+
self.currentValue.map { self.model.progress(for: $0) } ?? self.model.progress
1515
}
1616

1717
// MARK: - Initializer
@@ -20,6 +20,7 @@ public struct SUCircularProgress: View {
2020
/// - Parameters:
2121
/// - currentValue: Current progress.
2222
/// - model: A model that defines the appearance properties.
23+
@available(*, deprecated, message: "Set `currentValue` in the model instead.")
2324
public init(
2425
currentValue: CGFloat = 0,
2526
model: CircularProgressVM = .init()
@@ -28,6 +29,13 @@ public struct SUCircularProgress: View {
2829
self.model = model
2930
}
3031

32+
/// Initializer.
33+
/// - Parameters:
34+
/// - model: A model that defines the appearance properties.
35+
public init(model: CircularProgressVM = .init()) {
36+
self.model = model
37+
}
38+
3139
// MARK: - Body
3240

3341
public var body: some View {

Sources/ComponentsKit/Components/CircularProgress/UKCircularProgress.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@ open class UKCircularProgress: UIView, UKComponent {
1313
}
1414

1515
/// The current progress value.
16-
public var currentValue: CGFloat {
16+
public var currentValue: CGFloat? {
1717
didSet {
1818
self.updateProgress()
1919
}
2020
}
2121

22+
private var progress: CGFloat {
23+
self.currentValue.map { self.model.progress(for: $0) } ?? self.model.progress
24+
}
25+
2226
// MARK: - Subviews
2327

2428
/// The shape layer responsible for rendering the background.
@@ -42,6 +46,7 @@ open class UKCircularProgress: UIView, UKComponent {
4246
/// - Parameters:
4347
/// - initialValue: The initial progress value. Defaults to `0`.
4448
/// - model: The model that defines the appearance properties.
49+
@available(*, deprecated, message: "Set `currentValue` in the model instead.")
4550
public init(
4651
initialValue: CGFloat = 0,
4752
model: CircularProgressVM = .init()
@@ -55,6 +60,18 @@ open class UKCircularProgress: UIView, UKComponent {
5560
self.layout()
5661
}
5762

63+
/// Initializer.
64+
/// - Parameters:
65+
/// - model: The model that defines the appearance properties.
66+
public init(model: CircularProgressVM = .init()) {
67+
self.model = model
68+
super.init(frame: .zero)
69+
70+
self.setup()
71+
self.style()
72+
self.layout()
73+
}
74+
5875
public required init?(coder: NSCoder) {
5976
fatalError("init(coder:) has not been implemented")
6077
}
@@ -72,7 +89,7 @@ open class UKCircularProgress: UIView, UKComponent {
7289
}
7390
}
7491

75-
self.progressLayer.strokeEnd = self.model.progress(for: self.currentValue)
92+
self.progressLayer.strokeEnd = self.progress
7693
self.label.text = self.model.label
7794
}
7895

@@ -132,7 +149,7 @@ open class UKCircularProgress: UIView, UKComponent {
132149
CATransaction.begin()
133150
CATransaction.setAnimationDuration(self.model.animationDuration)
134151
CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: .linear))
135-
self.progressLayer.strokeEnd = self.model.progress(for: self.currentValue)
152+
self.progressLayer.strokeEnd = self.progress
136153
CATransaction.commit()
137154
}
138155

0 commit comments

Comments
 (0)