Skip to content

Commit c515514

Browse files
committed
move assets
1 parent 502309e commit c515514

File tree

3 files changed

+217
-5
lines changed

3 files changed

+217
-5
lines changed

Example/SpringText/Base.lproj/Main.storyboard

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
2020
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
2121
<subviews>
22-
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sIj-hc-Uk3" customClass="SPLabel" customModule="SpringText">
22+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sIj-hc-Uk3" customClass="TPCountLabel" customModule="SpringText">
2323
<rect key="frame" x="16" y="20" width="42" height="21"/>
2424
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
2525
<fontDescription key="fontDescription" type="system" pointSize="17"/>

Example/SpringText/ViewController.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@ import UIKit
1010
import SpringText
1111

1212
class ViewController: UIViewController {
13-
@IBOutlet weak var lblTitle: SPLabel!
13+
@IBOutlet weak var lblTitle: TPCountLabel!
1414

1515
override func viewDidLoad() {
16-
super.viewDidLoad()
17-
lblTitle.text = "OK"
18-
lblTitle.updateDisplay()
16+
lblTitle.configure(with:10)
1917
}
2018

2119
override func didReceiveMemoryWarning() {

SpringText/Classes/SPLabel.swift

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,220 @@
66
//
77

88
import UIKit
9+
import QuartzCore
10+
11+
extension UILabel {
12+
func textWidth() -> CGFloat {
13+
return UILabel.textWidth(label: self)
14+
}
15+
16+
class func textWidth(label: UILabel) -> CGFloat {
17+
return textWidth(label: label, text: label.text!)
18+
}
19+
20+
class func textWidth(label: UILabel, text: String) -> CGFloat {
21+
return textWidth(font: label.font, text: text)
22+
}
23+
24+
class func textWidth(font: UIFont, text: String) -> CGFloat {
25+
let myText = text as NSString
26+
27+
let rect = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
28+
let labelSize = myText.boundingRect(with: rect, options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
29+
return ceil(labelSize.width)
30+
}
31+
}
32+
33+
34+
extension TPCountLabel {
35+
func text(num: Int, hasWon: Bool = true) {
36+
self.hasWon = hasWon
37+
self.configure(with: num)
38+
self.animate()
39+
}
40+
}
41+
42+
extension Int {
43+
var currency: String {
44+
let numberFormatter = NumberFormatter()
45+
numberFormatter.numberStyle = .decimal
46+
// numberFormatter.locale = App.shared.locale
47+
numberFormatter.maximumFractionDigits = 0
48+
return numberFormatter.string(from: NSNumber(value: self))?.currency ?? "0"
49+
}
50+
}
51+
52+
extension String {
53+
var currency: String {
54+
let formatter = NumberFormatter()
55+
formatter.numberStyle = .decimal
56+
// formatter.locale = App.shared.locale
57+
formatter.maximumFractionDigits = 0
58+
59+
let currencyString = formatter.string(from: formatter.number(from: self) ?? 0) ?? "0"
60+
// currencyString = currencyString + "원"
61+
62+
return currencyString
63+
}
64+
65+
}
66+
67+
open class TPCountLabel: UILabel {
68+
var fullText = ""
69+
private var hasWon: Bool = true
70+
71+
private var scrollLayers: [CAScrollLayer] = []
72+
private var scrollLabels: [UILabel] = []
73+
private let duration = 0.7
74+
private let durationOffset = 0.2
75+
private let textsNotAnimated = [","]
76+
77+
public func configure(with number: Int) {
78+
let text = number.currency
79+
fullText = text
80+
clean()
81+
setupSubviews()
82+
}
83+
84+
func animate(ascending: Bool = true) {
85+
createAnimations(ascending: ascending)
86+
}
87+
88+
private func clean() {
89+
self.text = nil
90+
self.subviews.forEach { $0.removeFromSuperview() }
91+
self.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
92+
scrollLayers.removeAll()
93+
scrollLabels.removeAll()
94+
}
95+
96+
private func setupSubviews() {
97+
let stringArray = fullText.map { String($0) }
98+
var x: CGFloat = 0
99+
let y: CGFloat = 0
100+
if self.textAlignment == .center {
101+
if hasWon {
102+
self.text = "\(fullText)"
103+
} else {
104+
self.text = fullText
105+
}
106+
let w = UILabel.textWidth(font: self.font, text: self.text ?? "")
107+
self.text = "" // 초기화
108+
x = -(w / 2)
109+
} else if self.textAlignment == .right {
110+
if hasWon {
111+
self.text = "\(fullText)"
112+
} else {
113+
self.text = fullText
114+
}
115+
let w = UILabel.textWidth(font: self.font, text: self.text ?? "")
116+
self.text = "" // 초기화
117+
x = -w
118+
}
119+
120+
if hasWon {
121+
let wLabel = UILabel()
122+
wLabel.frame.origin = CGPoint(x: x, y: y)
123+
wLabel.textColor = textColor
124+
wLabel.font = font
125+
wLabel.text = ""
126+
wLabel.textAlignment = .center
127+
wLabel.sizeToFit()
128+
self.addSubview(wLabel)
129+
x += wLabel.bounds.width
130+
}
131+
132+
stringArray.enumerated().forEach { index, text in
133+
if textsNotAnimated.contains(text) {
134+
// 콤마
135+
let label = UILabel()
136+
label.frame.origin = CGPoint(x: x, y: y)
137+
label.textColor = textColor
138+
label.font = font
139+
label.text = text
140+
label.textAlignment = .center
141+
label.sizeToFit()
142+
self.addSubview(label)
143+
144+
x += label.bounds.width
145+
} else {
146+
// 숫자
147+
let label = UILabel()
148+
label.frame.origin = CGPoint(x: x, y: y)
149+
label.textColor = textColor
150+
label.font = font
151+
label.text = "0"
152+
label.textAlignment = .center
153+
label.sizeToFit()
154+
createScrollLayer(to: label, text: text)
155+
156+
x += label.bounds.width
157+
}
158+
}
159+
}
160+
161+
private func createScrollLayer(to label: UILabel, text: String) {
162+
let scrollLayer = CAScrollLayer()
163+
scrollLayer.frame = label.frame
164+
scrollLayers.append(scrollLayer)
165+
self.layer.addSublayer(scrollLayer)
166+
167+
createContentForLayer(scrollLayer: scrollLayer, text: text)
168+
}
169+
170+
private func createContentForLayer(scrollLayer: CAScrollLayer, text: String) {
171+
var textsForScroll: [String] = []
172+
guard let number = Int(Int(text)?.currency ?? "0") else { return }
173+
textsForScroll.append("0")
174+
for i in 0...9 {
175+
let str = String((number + i) % 10)
176+
textsForScroll.append(Int(str)?.currency ?? "0")
177+
}
178+
textsForScroll.append(text)
179+
180+
var height: CGFloat = 0
181+
for text in textsForScroll {
182+
let label = UILabel()
183+
label.text = text
184+
label.textColor = textColor
185+
label.font = font
186+
label.textAlignment = .center
187+
label.frame = CGRect(x: 0, y: height, width: scrollLayer.frame.width, height: scrollLayer.frame.height)
188+
scrollLayer.addSublayer(label.layer)
189+
scrollLabels.append(label)
190+
// height = label.frame.maxY + 5
191+
height = label.frame.maxY
192+
}
193+
}
194+
195+
private func createAnimations(ascending: Bool) {
196+
var offset: CFTimeInterval = 0.0
197+
198+
for scrollLayer in scrollLayers {
199+
let maxY = scrollLayer.sublayers?.last?.frame.origin.y ?? 0.0
200+
201+
let animation = CABasicAnimation(keyPath: "sublayerTransform.translation.y")
202+
animation.duration = duration + offset
203+
// animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
204+
205+
if ascending {
206+
animation.fromValue = maxY
207+
animation.toValue = 0
208+
} else {
209+
animation.fromValue = 0
210+
animation.toValue = maxY
211+
}
212+
213+
// scrollLayer.scrollMode = .vertically
214+
// custom key 설정
215+
scrollLayer.add(animation, forKey: nil)
216+
scrollLayer.scroll(to: CGPoint(x: 0, y: maxY))
217+
218+
offset += self.durationOffset
219+
}
220+
}
221+
}
222+
9223

10224
open class SPLabel: UILabel {
11225
public func updateDisplay() {

0 commit comments

Comments
 (0)