Skip to content

Commit cc9c4b8

Browse files
Merge pull request #38 from SimformSolutionsPvtLtd/develop
Develop
2 parents 830d736 + 5d8baa7 commit cc9c4b8

File tree

14 files changed

+433
-66
lines changed

14 files changed

+433
-66
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SSspinnerButton
1+
# SSSpinnerButton
22

33

44
SSSpinnerButton is an elegant button with a different spinner animations.
@@ -33,10 +33,10 @@ SSSpinnerButton is an elegant button with a different spinner animations.
3333
-
3434
import UIKit
3535
import SSSpinnerButton
36-
37-
**Carthage**
38-
39-
Add `github simformsolutions/SSSpinnerButton` to your project's Cartfile
36+
37+
**Carthage**
38+
39+
Add `github simformsolutions/SSSpinnerButton` to your project's Cartfile
4040

4141
**Manually**
4242
- Download and drop **SSSpinnerButton** folder in your project.

SSSpinnerButton Demo/Base.lproj/LaunchScreen.storyboard

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3+
<device id="retina6_1" orientation="portrait" appearance="light"/>
34
<dependencies>
4-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
5+
<deployment identifier="iOS"/>
6+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
57
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
68
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
79
</dependencies>
810
<scenes>
911
<!--View Controller-->
1012
<scene sceneID="EHf-IW-A2E">
1113
<objects>
12-
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
14+
<viewController modalPresentationStyle="fullScreen" id="01J-lp-oVM" sceneMemberID="viewController">
1315
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
14-
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
16+
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
1517
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16-
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
1718
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
19+
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
1820
</view>
1921
</viewController>
2022
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>

SSSpinnerButton Demo/Base.lproj/Main.storyboard

Lines changed: 123 additions & 44 deletions
Large diffs are not rendered by default.

SSSpinnerButton Demo/ViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class ViewController: UIViewController {
3131

3232
@IBAction func onSpinnnerButtonClick(_ sender: SSSpinnerButton) {
3333
sender.isSelected = !sender.isSelected
34-
let arr: [SpinnerType] = [.ballClipRotate, .ballSpinFade, .lineSpinFade, .ballRotateChase, .circleStrokeSpin, .ballClipRotate, .ballSpinFade, .lineSpinFade, .ballRotateChase, .circleStrokeSpin]
34+
let arr: [SpinnerType] = [.ballClipRotate, .ballSpinFade, .lineSpinFade, .ballRotateChase, .circleStrokeSpin, .ballClipRotate, .ballSpinFade, .lineSpinFade, .ballRotateChase, .pacman, .circleScaleMultiple, .circleWaveSpin]
3535

3636
// MARK: Start Animating
3737
sender.startAnimate(spinnerType: arr[sender.tag], spinnercolor: .white, spinnerSize: 20, complete: nil)

SSSpinnerButton.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |s|
1010
s.name = "SSSpinnerButton"
11-
s.version = "3.0.2"
11+
s.version = "3.1.0"
1212
s.summary = "SSSpinnerButton is an elegant button with a different spinner animations."
1313

1414
#s.description = "SSSpinnerButton is an elegant button with a different spinner animations."

SSSpinnerButton.xcodeproj/project.pbxproj

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
07FAD2B022A06F7E00FC1F9E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07FAD2A922A06F7E00FC1F9E /* Main.storyboard */; };
3131
07FAD2B122A06F7E00FC1F9E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07FAD2AB22A06F7E00FC1F9E /* AppDelegate.swift */; };
3232
51AAA60420C65EA5000F4BCD /* .tailor.yml in Resources */ = {isa = PBXBuildFile; fileRef = 51AAA60320C65EA5000F4BCD /* .tailor.yml */; };
33+
D346F19628242F900085293D /* SSPacman.swift in Sources */ = {isa = PBXBuildFile; fileRef = D346F19528242F900085293D /* SSPacman.swift */; };
34+
D346F19828242FD60085293D /* SSCircleScaleMultiple.swift in Sources */ = {isa = PBXBuildFile; fileRef = D346F19728242FD60085293D /* SSCircleScaleMultiple.swift */; };
35+
D3D692F22629BDFD0032EB92 /* SSCircleWaveSpin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3D692F12629BDFD0032EB92 /* SSCircleWaveSpin.swift */; };
3336
/* End PBXBuildFile section */
3437

3538
/* Begin PBXContainerItemProxy section */
@@ -82,6 +85,9 @@
8285
730FA84E2136AD4800F6116F /* SSSuccessMark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSSuccessMark.swift; sourceTree = "<group>"; };
8386
737852F82137B12B005A1EA6 /* SSErrorMark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSErrorMark.swift; sourceTree = "<group>"; };
8487
737852FA2137C745005A1EA6 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
88+
D346F19528242F900085293D /* SSPacman.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SSPacman.swift; sourceTree = "<group>"; };
89+
D346F19728242FD60085293D /* SSCircleScaleMultiple.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SSCircleScaleMultiple.swift; path = ../../../../../../Desktop/SSSpinnerButton/SSSpinnerButton/SpinerShapes/SpinnerShapeWithAnimation/SSCircleScaleMultiple.swift; sourceTree = "<group>"; };
90+
D3D692F12629BDFD0032EB92 /* SSCircleWaveSpin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSCircleWaveSpin.swift; sourceTree = "<group>"; };
8591
/* End PBXFileReference section */
8692

8793
/* Begin PBXFrameworksBuildPhase section */
@@ -173,11 +179,14 @@
173179
519BCB67219A946600F50E26 /* SSFailMark.swift */,
174180
51AAA5F120C64EF0000F4BCD /* SSBallRotateChase.swift */,
175181
51AAA5F220C64EF0000F4BCD /* SSBallSpinFadeLoader.swift */,
182+
D346F19728242FD60085293D /* SSCircleScaleMultiple.swift */,
176183
51AAA5F320C64EF0000F4BCD /* SSCircleStrokeSpin.swift */,
177184
51AAA5F420C64EF0000F4BCD /* SSLineSpinFadeLoader.swift */,
178185
51AAA5F520C64EF0000F4BCD /* SSSpinnerBallClipRotate.swift */,
179186
730FA84E2136AD4800F6116F /* SSSuccessMark.swift */,
180187
737852F82137B12B005A1EA6 /* SSErrorMark.swift */,
188+
D346F19528242F900085293D /* SSPacman.swift */,
189+
D3D692F12629BDFD0032EB92 /* SSCircleWaveSpin.swift */,
181190
);
182191
path = SpinnerShapeWithAnimation;
183192
sourceTree = "<group>";
@@ -259,7 +268,7 @@
259268
51AAA5D420C64ED3000F4BCD = {
260269
CreatedOnToolsVersion = 9.2;
261270
LastSwiftMigration = 1020;
262-
ProvisioningStyle = Automatic;
271+
ProvisioningStyle = Manual;
263272
};
264273
};
265274
};
@@ -325,14 +334,17 @@
325334
isa = PBXSourcesBuildPhase;
326335
buildActionMask = 2147483647;
327336
files = (
337+
D346F19828242FD60085293D /* SSCircleScaleMultiple.swift in Sources */,
328338
07FAD29E22A0679B00FC1F9E /* SSSuccessMark.swift in Sources */,
329339
07FAD2A022A067A300FC1F9E /* SpinnerTypes.swift in Sources */,
330340
07FAD29822A0678800FC1F9E /* SSFailMark.swift in Sources */,
331341
07FAD2A222A067AC00FC1F9E /* SSSpinnerButton.swift in Sources */,
332342
07FAD29A22A0678E00FC1F9E /* SSBallSpinFadeLoader.swift in Sources */,
333343
07FAD29B22A0679200FC1F9E /* SSCircleStrokeSpin.swift in Sources */,
334344
07FAD29722A0678300FC1F9E /* spinnerShape.swift in Sources */,
345+
D3D692F22629BDFD0032EB92 /* SSCircleWaveSpin.swift in Sources */,
335346
07FAD29D22A0679800FC1F9E /* SSSpinnerBallClipRotate.swift in Sources */,
347+
D346F19628242F900085293D /* SSPacman.swift in Sources */,
336348
07FAD29C22A0679500FC1F9E /* SSLineSpinFadeLoader.swift in Sources */,
337349
07FAD2A122A067A600FC1F9E /* Extensions.swift in Sources */,
338350
07FAD29922A0678A00FC1F9E /* SSBallRotateChase.swift in Sources */,
@@ -581,13 +593,15 @@
581593
buildSettings = {
582594
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
583595
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
584-
CODE_SIGN_STYLE = Automatic;
585-
DEVELOPMENT_TEAM = Y98X8JAPH6;
596+
CODE_SIGN_STYLE = Manual;
597+
CURRENT_PROJECT_VERSION = 1;
598+
DEVELOPMENT_TEAM = "";
586599
INFOPLIST_FILE = "$(SRCROOT)/SSSpinnerButton/Info.plist";
587600
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
588601
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
589602
PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSSpinnerButtonDemo;
590603
PRODUCT_NAME = "$(TARGET_NAME)";
604+
PROVISIONING_PROFILE_SPECIFIER = "";
591605
SWIFT_VERSION = 5.0;
592606
TARGETED_DEVICE_FAMILY = "1,2";
593607
};
@@ -598,13 +612,15 @@
598612
buildSettings = {
599613
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
600614
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
601-
CODE_SIGN_STYLE = Automatic;
602-
DEVELOPMENT_TEAM = Y98X8JAPH6;
615+
CODE_SIGN_STYLE = Manual;
616+
CURRENT_PROJECT_VERSION = 1;
617+
DEVELOPMENT_TEAM = "";
603618
INFOPLIST_FILE = "$(SRCROOT)/SSSpinnerButton/Info.plist";
604619
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
605620
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
606621
PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSSpinnerButtonDemo;
607622
PRODUCT_NAME = "$(TARGET_NAME)";
623+
PROVISIONING_PROFILE_SPECIFIER = "";
608624
SWIFT_VERSION = 5.0;
609625
TARGETED_DEVICE_FAMILY = "1,2";
610626
};
@@ -675,13 +691,15 @@
675691
buildSettings = {
676692
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
677693
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
678-
CODE_SIGN_STYLE = Automatic;
679-
DEVELOPMENT_TEAM = Y98X8JAPH6;
694+
CODE_SIGN_STYLE = Manual;
695+
CURRENT_PROJECT_VERSION = 1;
696+
DEVELOPMENT_TEAM = "";
680697
INFOPLIST_FILE = "$(SRCROOT)/SSSpinnerButton/Info.plist";
681698
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
682699
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
683700
PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSSpinnerButtonDemo;
684701
PRODUCT_NAME = "$(TARGET_NAME)";
702+
PROVISIONING_PROFILE_SPECIFIER = "";
685703
SWIFT_VERSION = 5.0;
686704
TARGETED_DEVICE_FAMILY = "1,2";
687705
};

SSSpinnerButton/Info.plist

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,15 @@
1818
<string>1.0</string>
1919
<key>CFBundleVersion</key>
2020
<string>$(CURRENT_PROJECT_VERSION)</string>
21+
<key>UILaunchStoryboardName</key>
22+
<string>LaunchScreen</string>
23+
<key>UIMainStoryboardFile</key>
24+
<string>Main</string>
25+
<key>UIRequiresFullScreen</key>
26+
<false/>
27+
<key>UISupportedInterfaceOrientations</key>
28+
<array>
29+
<string>UIInterfaceOrientationPortrait</string>
30+
</array>
2131
</dict>
2232
</plist>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// SSCirclePulse.swift
3+
// SSSpinnerButton
4+
//
5+
// Created by Pranay Patel on 16/04/21.
6+
// Copyright © 2021 Simform Solutions. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
class SSCircleScaleMultiple: SSSpinnerAnimationDelegate {
12+
13+
/// setup spinner layer
14+
///
15+
/// - Parameters:
16+
/// - layer: layer Parent layer (Button layer)
17+
/// - frame: frame of parant layer
18+
/// - color: color of spinner
19+
/// - spinnerSize: size of spinner layer
20+
func setupSpinnerAnimation(layer: CALayer, frame: CGRect, color: UIColor, spinnerSize: UInt?) {
21+
let sizeValue = min(frame.width, frame.height)
22+
let center = CGPoint(x: 0, y: 0)
23+
let duration: CFTimeInterval = 1
24+
let beginTime = CACurrentMediaTime()
25+
let beginTimes = [0, 0.2, 0.4]
26+
27+
// Scale animation
28+
let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
29+
30+
scaleAnimation.duration = duration
31+
scaleAnimation.fromValue = 0
32+
scaleAnimation.toValue = 1
33+
34+
// Opacity animation
35+
let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
36+
opacityAnimation.duration = duration
37+
opacityAnimation.keyTimes = [0, 0.05, 1]
38+
opacityAnimation.values = [0, 1, 0]
39+
40+
// Animation
41+
let animation = CAAnimationGroup()
42+
43+
animation.animations = [scaleAnimation, opacityAnimation]
44+
animation.timingFunction = CAMediaTimingFunction(name: .linear)
45+
animation.duration = duration
46+
animation.repeatCount = HUGE
47+
animation.isRemovedOnCompletion = false
48+
49+
// Draw balls
50+
for i in 0 ..< 3 {
51+
let circle = SpinnerShape.circle.layerWith(size: CGSize(width: sizeValue, height: sizeValue), color: color)
52+
let frame = CGRect(x: center.x, y: center.y, width: sizeValue, height: sizeValue)
53+
animation.beginTime = beginTime + beginTimes[i]
54+
circle.frame = frame
55+
circle.opacity = 0
56+
circle.add(animation, forKey: "animation")
57+
layer.addSublayer(circle)
58+
}
59+
}
60+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//
2+
// SSCircleWave.swift
3+
// SSSpinnerButton
4+
//
5+
// Created by Pranay Patel on 16/04/21.
6+
// Copyright © 2021 Simform Solutions. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
class SSCircleWaveSpin: SSSpinnerAnimationDelegate {
12+
13+
/// setup spinner layer
14+
///
15+
/// - Parameters:
16+
/// - layer: layer Parent layer (Button layer)
17+
/// - frame: frame of parant layer
18+
/// - color: color of spinner
19+
/// - spinnerSize: size of spinner
20+
var pulseLayers = [CAShapeLayer]()
21+
22+
func setupSpinnerAnimation(layer: CALayer, frame: CGRect, color: UIColor, spinnerSize: UInt?) {
23+
for _ in 0...3 {
24+
let pulseLayerPath = UIBezierPath(arcCenter: .zero, radius: CGFloat(spinnerSize ?? 0) , startAngle: CGFloat(0), endAngle: CGFloat(Double.pi * 2), clockwise: true)
25+
let pulseLayer = SpinnerLayers()
26+
pulseLayer.path = pulseLayerPath.cgPath
27+
pulseLayer.lineWidth = 1.0
28+
pulseLayer.fillColor = UIColor.clear.cgColor
29+
pulseLayer.lineCap = CAShapeLayerLineCap.round
30+
pulseLayer.position = CGPoint(x: CGFloat(spinnerSize ?? 0) , y: CGFloat(spinnerSize ?? 0))
31+
layer.addSublayer(pulseLayer)
32+
pulseLayers.append(pulseLayer)
33+
}
34+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
35+
self.animation(index: 0, color: color)
36+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
37+
self.animation(index: 1, color: color)
38+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
39+
self.animation(index: 2, color: color)
40+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
41+
self.animation(index: 3, color: color)
42+
}
43+
}
44+
}
45+
}
46+
}
47+
48+
func animation(index: Int, color: UIColor) {
49+
pulseLayers[index].strokeColor = color.cgColor
50+
let animation = CABasicAnimation(keyPath: "transform.scale")
51+
animation.duration = 1.5
52+
animation.toValue = 0.9
53+
animation.fromValue = 0.0
54+
animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
55+
animation.repeatCount = .infinity
56+
pulseLayers[index].add(animation, forKey: "scale")
57+
58+
let opacityAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
59+
opacityAnimation.duration = 2.0
60+
opacityAnimation.toValue = 0.0
61+
opacityAnimation.fromValue = 0.9
62+
opacityAnimation.timingFunction = CAMediaTimingFunction(name: .easeOut)
63+
opacityAnimation.repeatCount = .infinity
64+
pulseLayers[index].add(animation, forKey: "opacity")
65+
}
66+
}

0 commit comments

Comments
 (0)