Skip to content
This repository was archived by the owner on Nov 19, 2021. It is now read-only.

Commit 2c7bcb5

Browse files
committed
First Commit
1 parent 6d406bb commit 2c7bcb5

38 files changed

Lines changed: 4034 additions & 377 deletions

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## [1.0.0 - Swift 4.2](https://github.com/micheltlutz/MLTontiatorView/releases/tag/v1.0.0) (2018-12-04)
2+
3+
#### Add
4+
* initial project.
5+
6+
## Usage
7+
Example: ViewController > viewDidLoad
8+
9+
```swift
10+
let viewActivitySmall = MLTontiatorView()
11+
viewActivitySmall.spinnerSize = .MLSpinnerSizeSmall
12+
viewActivitySmall.spinnerColor = UIColor.purple
13+
self.view.addSubview(viewActivitySmall)
14+
viewActivitySmall.startAnimating()
15+
```

MLTontiatorView.podspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ Pod::Spec.new do |s|
77
s.social_media_url = 'https://twitter.com/michel_lutz'
88
s.authors = { "Michel Lutz" => "michel_lutz@icloud.com" }
99
s.source = { :git => "https://github.com/micheltlutz/MLTontiatorView.git", :tag => "v"+s.version.to_s }
10-
s.platforms = { :ios => "10.0", :osx => "10.10", :tvos => "9.0", :watchos => "2.0" }
10+
s.platforms = { :ios => "10.0", :tvos => "9.0" }
1111
s.requires_arc = true
1212

1313
s.default_subspec = "Core"
1414
s.subspec "Core" do |ss|
1515
ss.source_files = "Sources/**/*.swift"
1616
ss.framework = "Foundation"
17+
ss.framework = "UIKit"
1718
end
1819
end

MLTontiatorView.xcodeproj/project.pbxproj

Lines changed: 2 additions & 356 deletions
Large diffs are not rendered by default.

MLTontiatorView.xcworkspace/contents.xcworkspacedata

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ let package = Package(
2020
targets: [
2121
.target(
2222
name: "MLTontiatorView",
23-
dependencies: [],
23+
dependencies: ["UIKit"],
2424
path: "Sources"),
2525
.testTarget(
2626
name: "MLTontiatorViewTests",

Readme.md

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
# MLTontiatorView
22

3+
<p align="center">
4+
 <img width="300" height="300"src="http://micheltlutz.me/imagens/projetos/MLTontiatorView/MLAUDIOPLAYER.png">
5+
 </p>
6+
7+
38
[![Platforms](https://img.shields.io/cocoapods/p/MLTontiatorView.svg)](https://cocoapods.org/pods/MLTontiatorView)
49
[![License](https://img.shields.io/cocoapods/l/MLTontiatorView.svg)](https://raw.githubusercontent.com/micheltlutz/MLTontiatorView/master/LICENSE)
510

611
[![Swift Package Manager](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)
712
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
813
[![CocoaPods compatible](https://img.shields.io/cocoapods/v/MLTontiatorView.svg)](https://cocoapods.org/pods/MLTontiatorView)
914

10-
[![Travis](https://img.shields.io/travis/micheltlutz/MLTontiatorView/master.svg)](https://travis-ci.org/micheltlutz/MLTontiatorView/branches)
11-
[![SwiftFrameworkTemplate](https://img.shields.io/badge/SwiftFramework-Template-red.svg)](http://github.com/RahulKatariya/SwiftFrameworkTemplate)
1215

1316
A Simple Activity indicator view
1417

@@ -17,9 +20,34 @@ A Simple Activity indicator view
1720
- [Usage](#usage)
1821
- [License](#license)
1922

23+
24+
## Usage
25+
26+
```swift
27+
let viewActivitySmall = MLTontiatorView()
28+
viewActivitySmall.spinnerSize = .MLSpinnerSizeSmall
29+
viewActivitySmall.spinnerColor = UIColor.purple
30+
self.view.addSubview(viewActivitySmall)
31+
viewActivitySmall.startAnimating()
32+
```
33+
34+
## Result
35+
36+
<p align="center">
37+
 <img width="300" height="238"src="http://micheltlutz.me/imagens/projetos/MLTontiatorView/TOTIATORVIEW.gif">
38+
 </p>
39+
40+
## Docs
41+
42+
[Documentation](http://htmlpreview.github.io/?https://github.com/micheltlutz/MLTontiatorView/blob/develop/docs/index.html)
43+
44+
MLTontiatorView Docs (100% documented)
45+
46+
47+
2048
## Requirements
2149

22-
- iOS 8.0+ / Mac OS X 10.10+ / tvOS 9.0+ / watchOS 2.0+
50+
- iOS 10.0+ / tvOS 9.0+
2351
- Xcode 10.0+
2452

2553
## Installation
@@ -146,15 +174,14 @@ $ git submodule update --init --recursive
146174

147175
</p></details>
148176

149-
## Usage
150177

151178
## Contributing
152179

153180
Issues and pull requests are welcome!
154181

155182
## Author
156183

157-
Michel Lutz [@michel_lutz](https://twitter.com/michel_lutz)
184+
Michel Lutz [@michel_lutz](https://twitter.com/michel_lutz) - [My Site](http://micheltlutz.me)
158185

159186
## License
160187

Sources/Core/MLTontiatorView.swift

Lines changed: 227 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,228 @@
1-
//
2-
// MLTontiatorView.swift
3-
// MLTontiatorView
4-
//
5-
// Created by Michel Lutz on 02/10/17.
6-
// Copyright © 2017 micheltlutz. All rights reserved.
7-
//
8-
9-
import Foundation
10-
11-
class MLTontiatorView {
12-
13-
static let name = "MLTontiatorView"
14-
1+
////MIT License
2+
////
3+
////Copyright (c) 2018 Michel Anderson Lüz Teixeira
4+
////
5+
////Permission is hereby granted, free of charge, to any person obtaining a copy
6+
////of this software and associated documentation files (the "Software"), to deal
7+
////in the Software without restriction, including without limitation the rights
8+
////to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
////copies of the Software, and to permit persons to whom the Software is
10+
////furnished to do so, subject to the following conditions:
11+
////
12+
////The above copyright notice and this permission notice shall be included in all
13+
////copies or substantial portions of the Software.
14+
////
15+
////THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
////IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
////FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
////AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
////LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
////OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
////SOFTWARE.
22+
23+
import UIKit
24+
25+
/**
26+
class MLTontiatorView extends UIView
27+
28+
### Usage Example: ###
29+
````
30+
let viewActivitySmall = MLTontiatorView()
31+
viewActivitySmall.spinnerSize = .MLSpinnerSizeSmall
32+
viewActivitySmall.spinnerColor = UIColor.purple
33+
self.view.addSubview(viewActivitySmall)
34+
viewActivitySmall.startAnimating()
35+
````
36+
*/
37+
open class MLTontiatorView: UIView {
38+
/// Lib name
39+
public static let name = "MLTontiatorView"
40+
/// PI contant
41+
private let pi = 3.14159265359
42+
/**
43+
Enum with Spinners Size declarations
44+
*/
45+
public enum SpinnerSize: Int {
46+
case MLSpinnerSizeMini // suitable for frmae size (30, 30)
47+
case MLSpinnerSizeSmall // suitable for frame size (50, 50)
48+
case MLSpinnerSizeMedium // suitable for frame size (150, 150)
49+
case MLSpinnerSizeLarge // suitable for frame size (185, 185)
50+
case MLSpinnerSizeVeryLarge // suitable for frame size (220,220)
51+
}
52+
/**
53+
* radius of the spinner/rotator will be different in each Spinner Size
54+
* default = kAVSpinnerSizeTiny
55+
* if its kSHSpinnerSizeVeryLarge or kSHSpinnerSizeLarge, kSHSpinnerSizeMedium, can able to set two title, one title in.center of spinner and another in below the spinner
56+
*/
57+
open var spinnerSize: SpinnerSize?
58+
/**
59+
* spinner color
60+
* default = UIColor.white()
61+
*/
62+
open var spinnerColor: UIColor? = .gray
63+
64+
/**
65+
* spinner color
66+
* default = UIColor.white()
67+
*/
68+
open var spinnerGradientColors: [CGColor]?
69+
70+
/**
71+
* spinner angle indicates if spinner is open or not
72+
* default = 360
73+
*/
74+
open var angleSpinner: Double = 360
75+
76+
/**
77+
* stop animation when showing and dismissing the spinner
78+
*/
79+
private var stopShowingAndDismissingAnimation: Bool?
80+
/**
81+
* disable the user interaction of entire application
82+
* default = false
83+
*/
84+
private var disableEntireUserInteraction: Bool? {
85+
didSet {
86+
if disableEntireUserInteraction == true {
87+
UIApplication.shared.beginIgnoringInteractionEvents()
88+
}
89+
}
90+
}
91+
///Container for spinner
92+
private var viewActivitySquare: UIView?
93+
///Indicates if animations is running
94+
private var isAnimating: Bool?
95+
///Indicates a lineWidth start with 4.0
96+
private var lineWidth: CGFloat = 4.0
97+
///Indicates a defaultFrame start with .zero
98+
private var defaultFrame: CGRect = .zero
99+
/**
100+
This func Convert degrees in radians
101+
*/
102+
private func DEGREES_TO_RADIANS(degrees: Double) -> CGFloat {
103+
return CGFloat(((pi * degrees) / 180))
104+
}
105+
/**
106+
This func configure frames, line width and anchor besed on spinnerSize
107+
*/
108+
private func configure() {
109+
if let spinnerSize = spinnerSize {
110+
guard let spinnerSizeType = SpinnerSize.init(rawValue: spinnerSize.rawValue) else { return }
111+
switch spinnerSizeType {
112+
case .MLSpinnerSizeMini:
113+
frame = CGRect(x: 0, y: 0, width: 30, height: 30)
114+
defaultFrame = CGRect(x: 0, y: 0, width: 30, height: 30)
115+
lineWidth = 2.0
116+
case .MLSpinnerSizeSmall:
117+
frame = CGRect(x: 0, y: 0, width: 50, height: 50)
118+
defaultFrame = CGRect(x: 0, y: 0, width: 50, height: 50)
119+
lineWidth = 4.0
120+
case .MLSpinnerSizeMedium:
121+
frame = CGRect(x: 0, y: 0, width: 150, height: 150)
122+
defaultFrame = CGRect(x: 0, y: 0, width: 82, height: 82)
123+
lineWidth = 8.0
124+
case .MLSpinnerSizeLarge:
125+
frame = CGRect(x: 0, y: 0, width: 185, height: 185)
126+
defaultFrame = CGRect(x: 0, y: 0, width: 120, height: 120)
127+
lineWidth = 10.0
128+
case .MLSpinnerSizeVeryLarge:
129+
frame = CGRect(x: 0, y: 0, width: 220, height: 220)
130+
defaultFrame = CGRect(x: 0, y: 0, width: 150, height: 150)
131+
lineWidth = 12.0
132+
}
133+
heightAnchor.constraint(equalToConstant: frame.height).isActive = true
134+
widthAnchor.constraint(equalToConstant: frame.width).isActive = true
135+
}
136+
if spinnerGradientColors == nil {
137+
spinnerGradientColors = [(spinnerColor?.cgColor)!,
138+
(spinnerColor)!.withAlphaComponent(0.5).cgColor,
139+
(spinnerColor)!.withAlphaComponent(0.25).cgColor,
140+
(spinnerColor)!.withAlphaComponent(0.0).cgColor]
141+
}
142+
}
143+
/**
144+
This func create a CABasicAnimation for rotation animation
145+
*/
146+
@objc private func rotationAnimation() {
147+
let rotate = CABasicAnimation(keyPath: "transform.rotation")
148+
rotate.fromValue = NSNumber(value: 0.0)
149+
rotate.toValue = NSNumber(value: 6.2)
150+
rotate.repeatCount = Float(CGFloat.greatestFiniteMagnitude)
151+
rotate.duration = 1.5
152+
viewActivitySquare?.layer .add(rotate, forKey: "rotateRepeatedly")
153+
}
154+
/**
155+
This func create a CAGradientLayer
156+
157+
- Parameter frame: CGRect
158+
- returns: An CAGradientLayer
159+
*/
160+
private func createGradientLayer(frame: CGRect) -> CAGradientLayer {
161+
let gradient = CAGradientLayer()
162+
gradient.frame = frame
163+
gradient.colors = spinnerGradientColors!
164+
gradient.startPoint = CGPoint(x: 0, y: 0)
165+
gradient.endPoint = CGPoint(x: 0, y: 1)
166+
return gradient
167+
}
168+
/**
169+
This func create a CAShapeLayer
170+
171+
- Parameter path: UIBezierPath arc
172+
- returns: An CAShapeLayer
173+
*/
174+
private func createShapeLayer(path: UIBezierPath) -> CAShapeLayer {
175+
let shape = CAShapeLayer()
176+
shape.path = path.cgPath
177+
shape.lineCap = CAShapeLayerLineCap.round
178+
shape.fillColor = UIColor.clear.cgColor
179+
shape.strokeColor = UIColor.white.cgColor
180+
shape.lineWidth = lineWidth
181+
return shape
182+
}
183+
/**
184+
This func start animation and add observer
185+
*/
186+
open func startAnimating() {
187+
configure()
188+
viewActivitySquare = UIView(frame: defaultFrame)
189+
let lowerPath = UIBezierPath(arcCenter: (viewActivitySquare?.center)!,
190+
radius: (viewActivitySquare?.frame.size.width)! / 2.2,
191+
startAngle: DEGREES_TO_RADIANS(degrees: -5),
192+
endAngle: DEGREES_TO_RADIANS(degrees: angleSpinner),
193+
clockwise: true)
194+
195+
let lowerShape = self.createShapeLayer(path: lowerPath)
196+
let gradientLayer = createGradientLayer(frame: defaultFrame)
197+
gradientLayer.mask = lowerShape
198+
viewActivitySquare?.layer.addSublayer(gradientLayer)
199+
NotificationCenter.default.addObserver(self, selector: #selector(rotationAnimation),
200+
name: UIApplication.willEnterForegroundNotification, object: nil)
201+
202+
viewActivitySquare?.center = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height / 2)
203+
self.addSubview(viewActivitySquare!)
204+
self.rotationAnimation()
205+
UIView.animate(withDuration: (stopShowingAndDismissingAnimation == true) ? 0.0 : 0.5) { () -> Void in
206+
self.alpha = 1.0
207+
}
208+
}
209+
/**
210+
This func stop animation and remove observer
211+
*/
212+
open func stopAnimating() {
213+
UIView.animate(withDuration: (stopShowingAndDismissingAnimation == true) ? 0.0 : 0.5, animations: { () -> Void in
214+
self.alpha = 0.0
215+
}) { (finished) -> Void in
216+
if (finished == true) {
217+
self.isAnimating = false
218+
for view: UIView in self.subviews {
219+
view.removeFromSuperview()
220+
}
221+
if (self.disableEntireUserInteraction == true) {
222+
UIApplication.shared.endIgnoringInteractionEvents()
223+
}
224+
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
225+
}
226+
}
227+
}
15228
}

0 commit comments

Comments
 (0)