Skip to content

Commit db9e7f8

Browse files
Add 2 animation type
- Glare Loader - Custom Fave
1 parent ed72914 commit db9e7f8

10 files changed

Lines changed: 214 additions & 26 deletions

File tree

Example/ButtonClickStyle.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
4A62F3A22803115C00534ABA /* ButtonLayerExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A62F3572803115C00534ABA /* ButtonLayerExampleView.swift */; };
8080
4A62F3A32803115C00534ABA /* ButtonLayerExampleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4A62F3582803115C00534ABA /* ButtonLayerExampleView.xib */; };
8181
4A62F3B92803122700534ABA /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A62F3B82803122700534ABA /* SceneDelegate.swift */; };
82+
4A85B5A32803D59800DFD435 /* UIView+AnimationGlare.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A85B5A22803D59800DFD435 /* UIView+AnimationGlare.swift */; };
8283
4ADE26E42803837C00634B6C /* ExampleButtonsViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4ADE26E22803837C00634B6C /* ExampleButtonsViewController.storyboard */; };
8384
4ADE26E52803837C00634B6C /* ExampleButtonsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ADE26E32803837C00634B6C /* ExampleButtonsViewController.swift */; };
8485
4ADE26E7280383DC00634B6C /* ButtonClickStyle+Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ADE26E6280383DC00634B6C /* ButtonClickStyle+Buttons.swift */; };
@@ -165,6 +166,7 @@
165166
4A62F3572803115C00534ABA /* ButtonLayerExampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ButtonLayerExampleView.swift; sourceTree = "<group>"; };
166167
4A62F3582803115C00534ABA /* ButtonLayerExampleView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ButtonLayerExampleView.xib; sourceTree = "<group>"; };
167168
4A62F3B82803122700534ABA /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
169+
4A85B5A22803D59800DFD435 /* UIView+AnimationGlare.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+AnimationGlare.swift"; sourceTree = "<group>"; };
168170
4ADE26E22803837C00634B6C /* ExampleButtonsViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = ExampleButtonsViewController.storyboard; sourceTree = "<group>"; };
169171
4ADE26E32803837C00634B6C /* ExampleButtonsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExampleButtonsViewController.swift; sourceTree = "<group>"; };
170172
4ADE26E6280383DC00634B6C /* ButtonClickStyle+Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ButtonClickStyle+Buttons.swift"; sourceTree = "<group>"; };
@@ -234,6 +236,7 @@
234236
isa = PBXGroup;
235237
children = (
236238
4A14CBD02803437C00DA8A68 /* UIView+AnimationAlpha.swift */,
239+
4A85B5A22803D59800DFD435 /* UIView+AnimationGlare.swift */,
237240
4A14CBD12803437C00DA8A68 /* UIView+AnimationShadow.swift */,
238241
4A14CBD22803437C00DA8A68 /* UIView+AnimationPulsate.swift */,
239242
4A14CBD32803437C00DA8A68 /* UIView+AnimationAndroidPulse.swift */,
@@ -753,6 +756,7 @@
753756
4A62F3A12803115C00534ABA /* ExampleAnimationsViewController.swift in Sources */,
754757
4A62F38A2803115C00534ABA /* GradientBlueBasicButtonView.swift in Sources */,
755758
4A62F3732803115C00534ABA /* DesignableView.swift in Sources */,
759+
4A85B5A32803D59800DFD435 /* UIView+AnimationGlare.swift in Sources */,
756760
4A62F3A22803115C00534ABA /* ButtonLayerExampleView.swift in Sources */,
757761
4A62F3762803115C00534ABA /* XibView.swift in Sources */,
758762
4ADE26E52803837C00634B6C /* ExampleButtonsViewController.swift in Sources */,

Example/ButtonClickStyle/UI/Screen/ButtonList/ButtonListViewController.storyboard

Lines changed: 65 additions & 8 deletions
Large diffs are not rendered by default.

Example/ButtonClickStyle/UI/Screen/ButtonList/ButtonListViewController.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class ButtonListViewController: StoryboardController {
1818
var animationTypeLast: Int = 0
1919
var buttonTypeLast: Int = 0
2020

21-
21+
@IBOutlet var animationDurationLabel: UILabel!
22+
@IBOutlet var animationDurationSlider: UISlider!
2223

2324
@IBOutlet var colorClearButton: UIButton!
2425
var colorChanging: Bool = false
@@ -109,6 +110,8 @@ class ButtonListViewController: StoryboardController {
109110

110111
animationValueSlider.addTarget(self, action: #selector(onSliderValChanged(slider:event:)), for: .valueChanged)
111112

113+
animationDurationSlider.addTarget(self, action: #selector(onSliderDurationChanged(slider:event:)), for: .valueChanged)
114+
112115
buttonTypePicker.delegate = self
113116
buttonTypePicker.dataSource = self
114117
buttonTypePicker.tag = 0
@@ -217,11 +220,15 @@ class ButtonListViewController: StoryboardController {
217220
}
218221

219222
func getState() -> ButtonClick.State {
223+
224+
let dur: CGFloat? = animationDurationSlider.value != 0.0 ? CGFloat(animationDurationSlider.value) : nil
225+
220226
return .init(
221227
titleText: buttonTypes[buttonTypeLast],
222228
allSubviews: true, // animationType == ButtonClick._Style.color.rawValue ? false : allSubviewsSwitch.isOn,
223229
animationType: animationTypeLast,
224230
animationTypeValue: getValue(),
231+
animationDuration: dur,
225232
new: buttonTypeLast == 1,
226233
color: colorSelected,
227234
startClick: true,// createStartClick.isOn,
@@ -293,6 +300,7 @@ class ButtonListViewController: StoryboardController {
293300
}
294301
}
295302

303+
296304
let v = String(format: "%.2f",slider.value)
297305

298306
// animationTypes = [
@@ -313,6 +321,21 @@ class ButtonListViewController: StoryboardController {
313321
animationTypePicker.reloadAllComponents()
314322
}
315323

324+
325+
@objc func onSliderDurationChanged(slider: UISlider, event: UIEvent) {
326+
if let touchEvent = event.allTouches?.first {
327+
switch touchEvent.phase {
328+
case .ended:
329+
updateButtons()
330+
default:
331+
break
332+
}
333+
}
334+
let v = String(format: "%.2f",slider.value)
335+
animationDurationLabel.text = v
336+
}
337+
338+
316339
}
317340

318341
//MARK: - PickerView DataSource
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//
2+
// UIView+AnimationGlare\.swift
3+
// ButtonClickStyle_Example
4+
//
5+
// Created by Рустам Мотыгуллин on 11.04.2022.
6+
// Copyright © 2022 CocoaPods. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
extension UIView {
12+
13+
func buttonClickStyleGlare(alpha: CGFloat, color: UIColor? = nil, duration: CGFloat? = nil) {
14+
15+
// let snapshot = self.asImage().withRenderingMode(.alwaysTemplate)
16+
let snapshot = self.snapshot?.withRenderingMode(.alwaysTemplate)
17+
let imageView = UIImageView(image: snapshot)
18+
// Add it image view and render close to white
19+
var clr: UIColor = UIColor(white: 0.9, alpha: alpha)
20+
if let color = color {
21+
clr = color.withAlphaComponent(alpha)
22+
}
23+
imageView.tintColor = clr
24+
guard let image = imageView.snapshot else { return }
25+
// let image = imageView.asImage()// else { return }
26+
27+
let width = image.size.width
28+
let height = image.size.height
29+
// Create CALayer and add light content to it
30+
let shineLayer = CALayer()
31+
shineLayer.contents = image.cgImage
32+
shineLayer.frame = bounds
33+
34+
// create CAGradientLayer that will act as mask clear = not shown, opaque = rendered
35+
// Adjust gradient to increase width and angle of highlight
36+
let gradientLayer = CAGradientLayer()
37+
gradientLayer.colors = [UIColor.clear.cgColor,
38+
UIColor.black.withAlphaComponent(0.55).cgColor,
39+
UIColor.black.cgColor,
40+
UIColor.black.withAlphaComponent(0.55).cgColor,
41+
UIColor.clear.cgColor]
42+
gradientLayer.locations = [0.0, 0.35, 0.50, 0.65, 0.0]
43+
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
44+
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.15)
45+
46+
gradientLayer.frame = CGRect(x: -width, y: 0, width: width, height: height)
47+
// Create CA animation that will move mask from outside bounds left to outside bounds right
48+
let animation = CABasicAnimation(keyPath: "position.x")
49+
animation.byValue = width * 2
50+
// How long it takes for glare to move across button
51+
animation.duration = duration ?? 1.25
52+
// Repeat forever
53+
animation.repeatCount = Float.greatestFiniteMagnitude
54+
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
55+
56+
layer.addSublayer(shineLayer)
57+
shineLayer.mask = gradientLayer
58+
59+
// Add animation
60+
gradientLayer.add(animation, forKey: "shine")
61+
}
62+
63+
func buttonClickStyleGlareStop() {
64+
// Search all sublayer masks for "shine" animation and remove
65+
layer.sublayers?.forEach {
66+
$0.mask?.removeAnimation(forKey: "shine")
67+
}
68+
}
69+
}
70+
71+
extension UIView {
72+
// Helper to snapshot a view
73+
var snapshot: UIImage? {
74+
let renderer = UIGraphicsImageRenderer(size: bounds.size)
75+
76+
let image = renderer.image { context in
77+
layer.render(in: context.cgContext)
78+
}
79+
return image
80+
}
81+
}

Source/ButtonClickStyle/Animations/UIView+AnimationPulsate.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import UIKit
1212
extension UIView {
1313

1414
public func buttonClickStyleFave(mainView: UIView, secondView: UIView, color: UIColor? = nil, value: CGFloat, duration: CGFloat) {
15-
let maxSize = max(mainView.wwidth, mainView.hheight)
15+
let maxSize = max(mainView.wwidth, mainView.hheight) * 0.85
1616
let _y = (mainView.hheight / 2) - (maxSize / 2)
1717
let _x = (mainView.wwidth / 2) - (maxSize / 2)
1818

@@ -31,16 +31,18 @@ extension UIView {
3131

3232
secondView .addSubview(circle)
3333

34-
main(delay: 0.25) {
34+
let durr = 0.35
35+
36+
// main(delay: 0.25) {
3537

3638
let borderWidthAnimation: CABasicAnimation = CABasicAnimation(keyPath: "borderWidth")
3739
borderWidthAnimation.fromValue = circle.layer.borderWidth
3840
borderWidthAnimation.toValue = 0
39-
borderWidthAnimation.duration = 0.15
41+
borderWidthAnimation.duration = durr // * 0.8
4042
circle.layer.add(borderWidthAnimation, forKey: "borderWidth")
4143
circle.layer.borderWidth = 0
4244

43-
}
45+
// }
4446

4547
// let pulse = CASpringAnimation(keyPath: "transform.scale")
4648
// pulse.duration = 0.45
@@ -58,10 +60,10 @@ extension UIView {
5860
// circle.transform = .identity
5961
// }
6062

61-
UIView.animate(withDuration: 0.45,
62-
delay: 0.0,
63-
usingSpringWithDamping: 0.8,
64-
initialSpringVelocity: 6,
63+
UIView.animate(withDuration: durr ,
64+
delay: 0.00,
65+
usingSpringWithDamping: 2.8,
66+
initialSpringVelocity: 4,
6567
options: [.curveEaseOut],
6668
animations: {
6769
circle.transform = .identity
@@ -86,7 +88,7 @@ extension UIView {
8688
// })
8789

8890
UIView.animate(withDuration: 0.35, // 0.4,
89-
delay: 0.32,
91+
delay: 0.3,// 0.23,
9092
usingSpringWithDamping: 0.38,
9193
initialSpringVelocity: 10.0,
9294
options: [.allowUserInteraction],

Source/ButtonClickStyle/ButtonClickStyleAddViewsAnimation.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,18 @@ extension UIButton {
208208

209209
views.forEach {
210210
switch style {
211+
212+
case .glare(let alpha, let color):
213+
if event == .touchDown {
214+
215+
let v1 = $0
216+
main(delay: 10) {
217+
v1.buttonClickStyleGlareStop()
218+
}
219+
220+
$0.buttonClickStyleGlare(alpha: alpha, color: color, duration: dur)
221+
}
222+
211223
case .flash(let value):
212224
$0.buttonClickStyleFlash(value: value, duration: dur)
213225

Source/ButtonClickStyle/Style/ButtonClickStyle.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ extension ButtonClick {
1616
public enum Style: CaseIterable {
1717
case alpha( _ alpha: CGFloat = vDef) // 0.5 // HIDE Alpha
1818
case flash( _ alpha: CGFloat = vDef) // HIDE Flash More
19-
case shadow( _ alpha: CGFloat = vDef, color: UIColor? = nil) // 0.1845 add black shadow // ADD Shadow
19+
case shadow( _ alpha: CGFloat = vDef, color: UIColor? = nil) // 0.1845 add black shadow // ADD Shadow
2020
case color( _ alpha: CGFloat = vDef, color: UIColor = .red) // ADD Color
2121
case colorFlat( _ alpha: CGFloat = vDef, color: UIColor? = nil) // ADD Color
2222
case press( _ power: CGFloat = vDef) // MOVE Press
2323
case pulsate( _ power: CGFloat = vDef, new: Bool = false) // MOVE Pulsate
2424
case shake( _ power: CGFloat = vDef, new: Bool = false) // MOVE Shake
2525
case androidClickable(_ alpha: CGFloat = vDef, color: UIColor? = nil) // ADD Android Clickable
26-
case fave( _ power: CGFloat = vDef, color: UIColor? = nil) // Fave
26+
case fave( _ power: CGFloat = vDef, color: UIColor? = nil) //
27+
case glare( _ alpha: CGFloat = vDef, color: UIColor? = nil) //
28+
2729

2830
//MARK: All Cases, Indxs & Names
2931

@@ -44,7 +46,8 @@ extension ButtonClick {
4446
.shake(new: true),
4547
.androidClickable(),
4648
.androidClickable(color: .random()),
47-
.fave(vDef, color: .random())
49+
.fave(vDef, color: .random()),
50+
.glare(vDef, color: .random()),
4851
]
4952

5053
public func typeEasy() -> _Style {
@@ -77,6 +80,7 @@ extension ButtonClick {
7780
case .androidClickable(_, let color): return color == nil ? "AndroidClickable"
7881
: "AndroidClickable Color"
7982
case .fave(_,_): return "Fave"
83+
case .glare(_,_): return "Glare"
8084
}
8185
}
8286

@@ -94,6 +98,7 @@ extension ButtonClick {
9498
.shake(_,_): return .move
9599
case .androidClickable(_,_): return .tapGesture
96100
case .fave(_,_): return .tapGesture
101+
case .glare(_,_): return .loading
97102
}
98103
}
99104

@@ -121,6 +126,7 @@ extension ButtonClick {
121126
case .androidClickable(_, let color): return color == nil ? 11
122127
: 12
123128
case .fave(_, _): return 13
129+
case .glare(_, _): return 14
124130
}
125131
}
126132

@@ -138,6 +144,7 @@ extension ButtonClick {
138144
case .colorFlat(_, _): return 0.3 // .ms300
139145
case .androidClickable(_, _): return 1.0 // .s1
140146
case .fave(_, _): return 0.4
147+
case .glare(_, _): return 1.0
141148
}
142149
}
143150

@@ -171,6 +178,7 @@ extension ButtonClick {
171178
case 11: return .androidClickable(v, color: nil)
172179
case 12: return .androidClickable(v, color: color ?? UIColor.random())
173180
case 13: return .fave(v, color: color ?? UIColor.random())
181+
case 14: return .glare(v, color: color)
174182
default: return .alpha(v)
175183
}
176184
}()

Source/ButtonClickStyle/Style/ButtonClickStyleBase.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extension ButtonClick {
1515
case add = "Add"
1616
case addHide = "Add & Hide"
1717
case tapGesture = "TapGesture.Pulse"
18+
case loading = "Loading"
1819
case none = ""
1920
}
2021
}

Source/ButtonClickStyle/Style/ButtonClickStyleEmoji.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ extension ButtonClick.Style {
2020
case .pulsate(_, let new): return new ? "🆕" : ""
2121
case .shake(_, let new): return new ? "🆕" : ""
2222
case .androidClickable(_, let color): return color == nil ? "" : ""
23-
case .fave(_, _): return "🆕"
24-
23+
default: return "🆕"
2524
}
2625
}
2726

@@ -36,7 +35,7 @@ extension ButtonClick.Style {
3635
case .pulsate(_, _): return "💢"
3736
case .shake(_, _): return "🔛"
3837
case .androidClickable(_, _): return "🧿"
39-
case .fave(_, _): return ""
38+
default: return ""
4039
}
4140
}
4241

@@ -51,7 +50,7 @@ extension ButtonClick.Style {
5150
case .pulsate(_, _): return "♻️"
5251
case .shake(_, _): return "♻️"
5352
case .androidClickable(_, _): return ""
54-
case .fave(_, _): return ""
53+
default: return ""
5554
}
5655
}
5756

@@ -67,7 +66,7 @@ extension ButtonClick.Style {
6766
case .pulsate(_, let new): return new ? "" : ""
6867
case .shake(_, let new): return new ? "" : ""
6968
case .androidClickable(_, let color): return color == nil ? "⚫️" : "🔵"
70-
case .fave(_, _): return "🔵"
69+
default: return "🔵"
7170
}
7271
}
7372

Source/ButtonClickStyle/Style/ButtonClickStyleShort.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ extension ButtonClick {
2626
case androidClickable
2727
case androidClickableDark
2828
case fave
29+
case glare
2930
}
3031
}

0 commit comments

Comments
 (0)