Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SwiftUI-Version

![Badge](https://img.shields.io/badge/swift-white.svg?style=flat-square&logo=Swift)
![Badge](https://img.shields.io/badge/SwiftUI-001b87.svg?style=flat-square&logo=Swift&logoColor=black)
![Badge - Version](https://img.shields.io/badge/Version-0.7.0-1177AA?style=flat-square)
![Badge - Version](https://img.shields.io/badge/Version-0.7.1-1177AA?style=flat-square)
![Badge - Swift Package Manager](https://img.shields.io/badge/SPM-compatible-orange?style=flat-square)
![Badge - Platform](https://img.shields.io/badge/platform-mac_12|ios_15|watchos_8|tvos_15-yellow?style=flat-square)
![Badge - License](https://img.shields.io/badge/license-MIT-black?style=flat-square)
Expand Down Expand Up @@ -171,6 +171,6 @@ Once you have your Swift package set up, adding AnimateNumberText as a dependenc

```swift
dependencies: [
.package(url: "https://github.com/swift-man/AnimateNumberText.git", from: "0.7.0")
.package(url: "https://github.com/swift-man/AnimateNumberText.git", from: "0.7.1")
]
```
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Add AnimateNumberText to your Swift package dependencies.

```swift
dependencies: [
.package(url: "https://github.com/swift-man/AnimateNumberText.git", from: "0.7.0")
.package(url: "https://github.com/swift-man/AnimateNumberText.git", from: "0.7.1")
]
```

Expand Down
54 changes: 47 additions & 7 deletions Sources/AnimateNumberText/Private/TextType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ extension Array where Element == TextColumn {
filter(\.value.isNumber).count

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] Problem: digitOrdinal(at:) 메서드는 프로덕션 코드에서 더 이상 사용되지 않으며, 테스트 코드 외에는 전혀 사용되지 않습니다. 이는 죽은 코드(Dead Code)로, 유지보수 부담과 불필요한 복잡성을 증가시킵니다. Why it matters: 죽은 코드는 코드베이스의 품질을 저하시키고, 다른 개발자가 이를 오해하거나 의도적으로 사용할 위험이 있습니다. Suggested fix: digitOrdinal(at:) 메서드를 완전히 제거하고, 테스트 코드에서 digitOrdinalsByIndex()를 사용하도록 수정하세요. Confidence: High

Confidence score: 0.95

}

func digitOrdinalsByIndex() -> [Int: Int] {
var ordinalsByIndex: [Int: Int] = [:]
var digitOrdinal = 0

for index in indices where self[index].value.isNumber {
ordinalsByIndex[index] = digitOrdinal
digitOrdinal += 1
}

return ordinalsByIndex
}

func preservingReelPositions(_ positions: [UUID: Double]) -> [UUID: Double] {
var nextPositions: [UUID: Double] = [:]

Expand All @@ -115,22 +127,50 @@ extension Array where Element == TextColumn {
return nextPositions
}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
func reelPositions(updatingTo characters: [Character],
animation: AnimateNumberTextAnimation,
currentPositions: [UUID: Double]) -> [UUID: Double] {
let digitOrdinals = digitOrdinalsByIndex()
var nextPositions = preservingReelPositions(currentPositions)

for (index, character) in characters.enumerated() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] Problem: reelPositions(updatingTo:animation:currentPositions:) 메서드 내에서 digitOrdinalsByIndex()를 호출한 후, guard 문에서 let digitOrdinal = digitOrdinals[index]를 사용하지만, digitOrdinalsdigitOrdinalsByIndex()의 결과로 index가 존재하지 않으면 nil을 반환합니다. 이는 digitOrdinalnil일 수 있음을 의미하며, animation.reelTargetPosition에 전달될 때 nil이 전달될 수 있습니다. Why it matters: reelTargetPositionordinal 파라미터는 Int 타입이므로 nil이 전달되면 컴파일 오류가 발생합니다. Suggested fix: digitOrdinalnil일 경우 continue로 처리하는 guard 문을 추가하여 nil 처리를 명시적으로 보장하세요. Confidence: Medium

Confidence score: 0.88

let targetValue = TextType(character)
guard canAnimateDigitChange(to: targetValue, index: index),
let digit = targetValue.digitValue,
let digitOrdinal = digitOrdinals[index] else {
continue
}

let column = self[index]
let currentPosition = nextPositions[column.id]
?? Double(column.value.digitValue ?? digit)
nextPositions[column.id] = animation.reelTargetPosition(from: currentPosition,
to: digit,
ordinal: digitOrdinal)
}

return nextPositions
}

func canAnimateDigitChange(to value: Character, index: Int) -> Bool {
canAnimateDigitChange(to: TextType(value), index: index)
}

func canAnimateDigitChange(to value: TextType, index: Int) -> Bool {
guard indices.contains(index) else { return false }

return self[index].value.isNumber && TextType(value).isNumber
return self[index].value.isNumber && value.isNumber
}

func needsUpdate(to value: Character, index: Int) -> Bool {
guard indices.contains(index) else { return false }

return self[index].value != TextType(value)
needsUpdate(to: TextType(value), index: index)
}

func digitOrdinal(at index: Int) -> Int? {
guard indices.contains(index), self[index].value.isNumber else { return nil }
func needsUpdate(to value: TextType, index: Int) -> Bool {
guard indices.contains(index) else { return false }

return self[..<index].filter(\.value.isNumber).count
return self[index].value != value
}

mutating func set(_ value: Character, index: Int) {
Expand Down
20 changes: 5 additions & 15 deletions Sources/AnimateNumberText/Public/AnimateNumberText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,12 @@ public struct AnimateNumberText: View {
@MainActor
private func settingSmoothAnimationRange(_ characters: [Character]) {
let digitCount = animationRange.digitCount
let digitOrdinals = animationRange.digitOrdinalsByIndex()

for (index, value) in characters.enumerated()
where animationRange.needsUpdate(to: value, index: index)
&& animationRange.canAnimateDigitChange(to: value, index: index) {
let digitOrdinal = animationRange.digitOrdinal(at: index) ?? index
let digitOrdinal = digitOrdinals[index] ?? index

withAnimation(animation.digitAnimation(at: digitOrdinal,
digitCount: digitCount)) {
Expand All @@ -272,23 +273,12 @@ public struct AnimateNumberText: View {
@MainActor
private func settingReelAnimationRange(_ characters: [Character]) {
synchronizeReelPositions()
var nextPositions = reelPositions
let nextPositions = animationRange.reelPositions(updatingTo: characters,
animation: animation,
currentPositions: reelPositions)

for (index, value) in characters.enumerated()
where animationRange.canAnimateDigitChange(to: value, index: index) {
guard let digit = TextType(value).digitValue,
let digitOrdinal = animationRange.digitOrdinal(at: index) else {
continue
}

let columnID = animationRange[index].id
let currentPosition = reelPositions[columnID]
?? Double(animationRange[index].value.digitValue ?? digit)
let targetPosition = animation.reelTargetPosition(from: currentPosition,
to: digit,
ordinal: digitOrdinal)

nextPositions[columnID] = targetPosition
animationRange.set(value, index: index)
}

Expand Down
37 changes: 31 additions & 6 deletions Tests/AnimateNumberTextTests/AnimateNumberTextTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ struct AnimateNumberTextTests {
}

@Test
func digitOrdinalSkipsFormattedCharacters() {
func digitOrdinalsByIndexSkipsFormattedCharacters() {
let columns = [
TextColumn(value: .number(3)),
TextColumn(value: .number(0)),
Expand All @@ -289,11 +289,12 @@ struct AnimateNumberTextTests {
TextColumn(value: .string("s"))
]

#expect(columns.digitOrdinal(at: 0) == 0)
#expect(columns.digitOrdinal(at: 1) == 1)
#expect(columns.digitOrdinal(at: 2) == 2)
#expect(columns.digitOrdinal(at: 3) == nil)
#expect(columns.digitOrdinal(at: 4) == 3)
#expect(columns.digitOrdinalsByIndex() == [
0: 0,
1: 1,
2: 2,
4: 3
])
}

@Test
Expand Down Expand Up @@ -390,4 +391,28 @@ struct AnimateNumberTextTests {
#expect(animation.reelTargetPosition(from: 5, to: 5, ordinal: 0) == 15)
#expect(animation.reelTargetPosition(from: 5, to: 5, ordinal: 1) == -5)
}

@Test
func reelPositionsSpinUnchangedDigitsThroughUpdatePath() {
let columns = [
TextColumn(value: .number(3)),
TextColumn(value: .number(0)),
TextColumn(value: .number(1)),
TextColumn(value: .string(".")),
TextColumn(value: .number(9))
]
let animation = AnimateNumberTextAnimation.reel(spinningDuration: 0.9,
settleDuration: 0.25,
revolutions: 1)
let currentPositions = columns.currentDigitPositions()

let nextPositions = columns.reelPositions(updatingTo: Swift.Array("301.9"),
animation: animation,
currentPositions: currentPositions)

#expect(nextPositions[columns[0].id] == 13)
#expect(nextPositions[columns[1].id] == -10)
#expect(nextPositions[columns[2].id] == 11)
#expect(nextPositions[columns[4].id] == -1)
}
}
Loading