diff --git a/Example/GradientLoadingBar.xcodeproj/project.pbxproj b/Example/GradientLoadingBar.xcodeproj/project.pbxproj index 7a5c048..ad21024 100644 --- a/Example/GradientLoadingBar.xcodeproj/project.pbxproj +++ b/Example/GradientLoadingBar.xcodeproj/project.pbxproj @@ -8,15 +8,22 @@ /* Begin PBXBuildFile section */ 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; - 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; + 607FACD81AFB9204008FA782 /* BasicExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* BasicExampleViewController.swift */; }; 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 77357BD34CFF2778341F80E8 /* Pods_GradientLoadingBar_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03CD5D69D7C3FBBDBF5FABBB /* Pods_GradientLoadingBar_Example.framework */; }; 8020C040972E902A8CCAA9E7 /* Pods_GradientLoadingBar_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 434E3C8A6E245A38C2831E73 /* Pods_GradientLoadingBar_Tests.framework */; }; 970738871FA7286400930D92 /* UIColor+InitializersTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 970738841FA7286400930D92 /* UIColor+InitializersTestCase.swift */; }; + 972CFBCC2138849A006F14C9 /* SafeAreaExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 972CFBCB2138849A006F14C9 /* SafeAreaExampleViewController.swift */; }; + 97464E60213725B50097183A /* BlueFilledButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97464E5F213725B50097183A /* BlueFilledButton.swift */; }; + 97464E62213725C80097183A /* BlueBorderedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97464E61213725C80097183A /* BlueBorderedButton.swift */; }; + 97464E65213726A10097183A /* UIColor+CustomColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97464E64213726A10097183A /* UIColor+CustomColors.swift */; }; + 97464E6721372BCD0097183A /* AdvancedExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97464E6621372BCD0097183A /* AdvancedExampleViewController.swift */; }; + 97464E6921372C010097183A /* NavigationBarExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97464E6821372C010097183A /* NavigationBarExampleViewController.swift */; }; 974E3F1C1FF2AA4400C96A59 /* DurationsTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 974E3F161FF2A85600C96A59 /* DurationsTestCase.swift */; }; 974E3F221FF2DEAA00C96A59 /* GradientLoadingBarViewModelTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 974E3F211FF2DEAA00C96A59 /* GradientLoadingBarViewModelTestCase.swift */; }; + 97FA595B213184DF00CCD446 /* Observable+ObserveDistinctTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97FA595A213184DF00CCD446 /* Observable+ObserveDistinctTestCase.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -39,15 +46,22 @@ 607FACD01AFB9204008FA782 /* GradientLoadingBar_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GradientLoadingBar_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 607FACD71AFB9204008FA782 /* BasicExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicExampleViewController.swift; sourceTree = ""; }; 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 607FACE51AFB9204008FA782 /* GradientLoadingBar_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GradientLoadingBar_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 970738841FA7286400930D92 /* UIColor+InitializersTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+InitializersTestCase.swift"; sourceTree = ""; }; + 972CFBCB2138849A006F14C9 /* SafeAreaExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafeAreaExampleViewController.swift; sourceTree = ""; }; + 97464E5F213725B50097183A /* BlueFilledButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlueFilledButton.swift; sourceTree = ""; }; + 97464E61213725C80097183A /* BlueBorderedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlueBorderedButton.swift; sourceTree = ""; }; + 97464E64213726A10097183A /* UIColor+CustomColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+CustomColors.swift"; sourceTree = ""; }; + 97464E6621372BCD0097183A /* AdvancedExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedExampleViewController.swift; sourceTree = ""; }; + 97464E6821372C010097183A /* NavigationBarExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarExampleViewController.swift; sourceTree = ""; }; 974E3F161FF2A85600C96A59 /* DurationsTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DurationsTestCase.swift; sourceTree = ""; }; 974E3F211FF2DEAA00C96A59 /* GradientLoadingBarViewModelTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientLoadingBarViewModelTestCase.swift; sourceTree = ""; }; + 97FA595A213184DF00CCD446 /* Observable+ObserveDistinctTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+ObserveDistinctTestCase.swift"; sourceTree = ""; }; C06CA4DFA1DCB931095ABD3D /* GradientLoadingBar.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = GradientLoadingBar.podspec; path = ../GradientLoadingBar.podspec; sourceTree = ""; }; F76834BE9E43CA11377EC030 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; FECB95A4857728345199461F /* Pods-GradientLoadingBar_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GradientLoadingBar_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GradientLoadingBar_Tests/Pods-GradientLoadingBar_Tests.debug.xcconfig"; sourceTree = ""; }; @@ -97,8 +111,13 @@ 607FACD21AFB9204008FA782 /* Example for GradientLoadingBar */ = { isa = PBXGroup; children = ( + 97464E63213726920097183A /* Extensions */, + 97464E5E213725A20097183A /* Views */, + 607FACD71AFB9204008FA782 /* BasicExampleViewController.swift */, + 972CFBCB2138849A006F14C9 /* SafeAreaExampleViewController.swift */, + 97464E6621372BCD0097183A /* AdvancedExampleViewController.swift */, + 97464E6821372C010097183A /* NavigationBarExampleViewController.swift */, 607FACD51AFB9204008FA782 /* AppDelegate.swift */, - 607FACD71AFB9204008FA782 /* ViewController.swift */, 607FACD91AFB9204008FA782 /* Main.storyboard */, 607FACDC1AFB9204008FA782 /* Images.xcassets */, 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, @@ -157,10 +176,28 @@ isa = PBXGroup; children = ( 970738841FA7286400930D92 /* UIColor+InitializersTestCase.swift */, + 97FA595A213184DF00CCD446 /* Observable+ObserveDistinctTestCase.swift */, ); path = Extensions; sourceTree = ""; }; + 97464E5E213725A20097183A /* Views */ = { + isa = PBXGroup; + children = ( + 97464E5F213725B50097183A /* BlueFilledButton.swift */, + 97464E61213725C80097183A /* BlueBorderedButton.swift */, + ); + name = Views; + sourceTree = ""; + }; + 97464E63213726920097183A /* Extensions */ = { + isa = PBXGroup; + children = ( + 97464E64213726A10097183A /* UIColor+CustomColors.swift */, + ); + name = Extensions; + sourceTree = ""; + }; 974E3F151FF2A85600C96A59 /* Structs */ = { isa = PBXGroup; children = ( @@ -470,8 +507,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, + 607FACD81AFB9204008FA782 /* BasicExampleViewController.swift in Sources */, + 972CFBCC2138849A006F14C9 /* SafeAreaExampleViewController.swift in Sources */, + 97464E6721372BCD0097183A /* AdvancedExampleViewController.swift in Sources */, + 97464E65213726A10097183A /* UIColor+CustomColors.swift in Sources */, 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, + 97464E6921372C010097183A /* NavigationBarExampleViewController.swift in Sources */, + 97464E62213725C80097183A /* BlueBorderedButton.swift in Sources */, + 97464E60213725B50097183A /* BlueFilledButton.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -482,6 +525,7 @@ 970738871FA7286400930D92 /* UIColor+InitializersTestCase.swift in Sources */, 974E3F221FF2DEAA00C96A59 /* GradientLoadingBarViewModelTestCase.swift in Sources */, 974E3F1C1FF2AA4400C96A59 /* DurationsTestCase.swift in Sources */, + 97FA595B213184DF00CCD446 /* Observable+ObserveDistinctTestCase.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/GradientLoadingBar/AdvancedExampleViewController.swift b/Example/GradientLoadingBar/AdvancedExampleViewController.swift new file mode 100644 index 0000000..2994116 --- /dev/null +++ b/Example/GradientLoadingBar/AdvancedExampleViewController.swift @@ -0,0 +1,59 @@ +// +// AdvancedExampleViewController.swift +// GradientLoadingBar_Example +// +// Created by Felix Mau on 29.08.18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit +import GradientLoadingBar + +class AdvancedExampleViewController: UIViewController { + // MARK: - Outlets + + @IBOutlet var customSuperviewButton: BlueBorderedButton! + @IBOutlet var customGradientColorsButton: BlueBorderedButton! + + // MARK: - Private properties + + private var buttonGradientLoadingBar: GradientLoadingBar? + private var customGradientColorsGradientLoadingBar: GradientLoadingBar? + + // MARK: - Public methods + + override func viewDidLoad() { + super.viewDidLoad() + + buttonGradientLoadingBar = GradientLoadingBar(height: 3.0, + onView: customSuperviewButton) + + // Source: https://color.adobe.com/Pink-Flamingo-color-theme-10343714/ + customGradientColorsGradientLoadingBar = BottomGradientLoadingBar(height: 3.0, + gradientColorList: [ + UIColor(hex: "#f2526e"), + UIColor(hex: "#f17a97"), + UIColor(hex: "#f3bcc8"), + UIColor(hex: "#6dddf2"), + UIColor(hex: "#c1f0f4") + ], + onView: customGradientColorsButton) + } + + @IBAction func customSuperviewButtonTouchUpInside(_: Any) { + buttonGradientLoadingBar?.toggle() + } + + @IBAction func customGradientColorsButtonTouchUpInside(_: Any) { + customGradientColorsGradientLoadingBar?.toggle() + } +} + +// MARK: - UIBarPositioningDelegate + +// Notice: Delegate is setted-up via storyboard. +extension AdvancedExampleViewController: UINavigationBarDelegate { + func position(for _: UIBarPositioning) -> UIBarPosition { + return .topAttached + } +} diff --git a/Example/GradientLoadingBar/Base.lproj/LaunchScreen.xib b/Example/GradientLoadingBar/Base.lproj/LaunchScreen.xib index 8b30891..471bf97 100644 --- a/Example/GradientLoadingBar/Base.lproj/LaunchScreen.xib +++ b/Example/GradientLoadingBar/Base.lproj/LaunchScreen.xib @@ -1,11 +1,11 @@ - + - + @@ -14,7 +14,29 @@ + + + + + + + + + + + + diff --git a/Example/GradientLoadingBar/Base.lproj/Main.storyboard b/Example/GradientLoadingBar/Base.lproj/Main.storyboard index 53c1b49..efa758d 100644 --- a/Example/GradientLoadingBar/Base.lproj/Main.storyboard +++ b/Example/GradientLoadingBar/Base.lproj/Main.storyboard @@ -1,18 +1,19 @@ - + - + + - + - + @@ -21,122 +22,343 @@ - - + + + + + + + + + + + + + + + + + - - - - - - - + - - + + + + + + + - + + + + + + + - - - + + + + + + + - - - - - - - - - + + - + - - + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/GradientLoadingBar/BasicExampleViewController.swift b/Example/GradientLoadingBar/BasicExampleViewController.swift new file mode 100644 index 0000000..d89ec42 --- /dev/null +++ b/Example/GradientLoadingBar/BasicExampleViewController.swift @@ -0,0 +1,38 @@ +// +// BasicExampleViewController.swift +// GradientLoadingBar_Example +// +// Created by fxm90 on 09/30/2017. +// Copyright (c) 2017 fxm90. All rights reserved. +// + +import UIKit +import GradientLoadingBar + +class BasicExampleViewController: UIViewController { + // MARK: - Public methods + + @IBAction func showButtonTouchUpInside(_: Any) { + let gradientLoadingBar = GradientLoadingBar.shared + gradientLoadingBar.show() + } + + @IBAction func toggleButtonTouchUpInside(_: Any) { + let gradientLoadingBar = GradientLoadingBar.shared + gradientLoadingBar.toggle() + } + + @IBAction func hideButtonTouchUpInside(_: Any) { + let gradientLoadingBar = GradientLoadingBar.shared + gradientLoadingBar.hide() + } +} + +// MARK: - UIBarPositioningDelegate + +// Notice: Delegate is setted-up via storyboard. +extension BasicExampleViewController: UINavigationBarDelegate { + func position(for _: UIBarPositioning) -> UIBarPosition { + return .topAttached + } +} diff --git a/Example/GradientLoadingBar/BlueBorderedButton.swift b/Example/GradientLoadingBar/BlueBorderedButton.swift new file mode 100644 index 0000000..a3a1b84 --- /dev/null +++ b/Example/GradientLoadingBar/BlueBorderedButton.swift @@ -0,0 +1,36 @@ +// +// BlueBorderedButton.swift +// GradientLoadingBar_Example +// +// Created by Felix Mau on 29.08.18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit + +class BlueBorderedButton: UIButton { + // MARK: - Initializer + + override init(frame: CGRect) { + super.init(frame: frame) + + commonInit() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + commonInit() + } + + // MARK: - Private methods + + private func commonInit() { + backgroundColor = .clear + tintColor = .aquaBlue + + layer.cornerRadius = 4.0 + layer.borderColor = UIColor.aquaBlue.cgColor + layer.borderWidth = 1.0 + } +} diff --git a/Example/GradientLoadingBar/BlueFilledButton.swift b/Example/GradientLoadingBar/BlueFilledButton.swift new file mode 100644 index 0000000..edcab9a --- /dev/null +++ b/Example/GradientLoadingBar/BlueFilledButton.swift @@ -0,0 +1,34 @@ +// +// BlueButton.swift +// GradientLoadingBar_Example +// +// Created by Felix Mau on 29.08.18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit + +class BlueFilledButton: UIButton { + // MARK: - Initializer + + override init(frame: CGRect) { + super.init(frame: frame) + + commonInit() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + commonInit() + } + + // MARK: - Private methods + + private func commonInit() { + tintColor = .white + backgroundColor = .aquaBlue + + layer.cornerRadius = 4.0 + } +} diff --git a/Example/GradientLoadingBar/Images.xcassets/Contents.json b/Example/GradientLoadingBar/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Example/GradientLoadingBar/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/Contents.json b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/home.imageset/Contents.json b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/home.imageset/Contents.json new file mode 100644 index 0000000..d675922 --- /dev/null +++ b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/home.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "home.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/home.imageset/home.pdf b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/home.imageset/home.pdf new file mode 100644 index 0000000..ea0e25a Binary files /dev/null and b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/home.imageset/home.pdf differ diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/idea.imageset/Contents.json b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/idea.imageset/Contents.json new file mode 100644 index 0000000..263bb9f --- /dev/null +++ b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/idea.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "idea.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/idea.imageset/idea.pdf b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/idea.imageset/idea.pdf new file mode 100644 index 0000000..8c23797 Binary files /dev/null and b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/idea.imageset/idea.pdf differ diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/iphone_x.imageset/Contents.json b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/iphone_x.imageset/Contents.json new file mode 100644 index 0000000..1b7b2d7 --- /dev/null +++ b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/iphone_x.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "iphone_x.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/iphone_x.imageset/iphone_x.pdf b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/iphone_x.imageset/iphone_x.pdf new file mode 100644 index 0000000..eca2a6a Binary files /dev/null and b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/iphone_x.imageset/iphone_x.pdf differ diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/rocket.imageset/Contents.json b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/rocket.imageset/Contents.json new file mode 100644 index 0000000..541d052 --- /dev/null +++ b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/rocket.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "rocket.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/rocket.imageset/rocket.pdf b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/rocket.imageset/rocket.pdf new file mode 100644 index 0000000..4bb9759 Binary files /dev/null and b/Example/GradientLoadingBar/Images.xcassets/iOS 11 Glyphen/rocket.imageset/rocket.pdf differ diff --git a/Example/GradientLoadingBar/NavigationBarExampleViewController.swift b/Example/GradientLoadingBar/NavigationBarExampleViewController.swift new file mode 100644 index 0000000..fb1b304 --- /dev/null +++ b/Example/GradientLoadingBar/NavigationBarExampleViewController.swift @@ -0,0 +1,49 @@ +// +// NavigationBarExampleViewController.swift +// GradientLoadingBar_Example +// +// Created by Felix Mau on 29.08.18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit +import GradientLoadingBar + +class NavigationBarExampleViewController: UIViewController { + // MARK: - Outlets + + @IBOutlet var navigationBar: UINavigationBar! + + // MARK: - Private properties + + private var gradientLoadingBar: BottomGradientLoadingBar? + + // MARK: - Public methods + + override func viewDidLoad() { + super.viewDidLoad() + + gradientLoadingBar = BottomGradientLoadingBar(onView: navigationBar) + } + + @IBAction func showButtonTouchUpInside(_: Any) { + gradientLoadingBar?.show() + } + + @IBAction func toggleButtonTouchUpInside(_: Any) { + gradientLoadingBar?.toggle() + } + + @IBAction func hideButtonTouchUpInside(_: Any) { + gradientLoadingBar?.hide() + } +} + +// MARK: - UIBarPositioningDelegate + +// Notice: Delegate is setted-up via storyboard. +extension NavigationBarExampleViewController: UINavigationBarDelegate { + func position(for _: UIBarPositioning) -> UIBarPosition { + return .topAttached + } +} diff --git a/Example/GradientLoadingBar/SafeAreaExampleViewController.swift b/Example/GradientLoadingBar/SafeAreaExampleViewController.swift new file mode 100644 index 0000000..9316d22 --- /dev/null +++ b/Example/GradientLoadingBar/SafeAreaExampleViewController.swift @@ -0,0 +1,39 @@ +// +// SafeAreaExampleViewController.swift +// GradientLoadingBar_Example +// +// Created by Felix Mau on 30.08.18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit +import GradientLoadingBar + +class SafeAreaExampleViewController: UIViewController { + // MARK: - Private properties + + let safeAreaGradientLoadingBar = SafeAreaGradientLoadingBar() + + // MARK: - Public methods + + @IBAction func showButtonTouchUpInside(_: Any) { + safeAreaGradientLoadingBar.show() + } + + @IBAction func toggleButtonTouchUpInside(_: Any) { + safeAreaGradientLoadingBar.toggle() + } + + @IBAction func hideButtonTouchUpInside(_: Any) { + safeAreaGradientLoadingBar.hide() + } +} + +// MARK: - UIBarPositioningDelegate + +// Notice: Delegate is setted-up via storyboard. +extension SafeAreaExampleViewController: UINavigationBarDelegate { + func position(for _: UIBarPositioning) -> UIBarPosition { + return .topAttached + } +} diff --git a/Example/GradientLoadingBar/UIColor+CustomColors.swift b/Example/GradientLoadingBar/UIColor+CustomColors.swift new file mode 100644 index 0000000..e5a421b --- /dev/null +++ b/Example/GradientLoadingBar/UIColor+CustomColors.swift @@ -0,0 +1,13 @@ +// +// UIColor+CustomColors.swift +// GradientLoadingBar_Example +// +// Created by Felix Mau on 29.08.18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit + +extension UIColor { + static let aquaBlue = UIColor(hex: "#4990e2") +} diff --git a/Example/GradientLoadingBar/ViewController.swift b/Example/GradientLoadingBar/ViewController.swift deleted file mode 100644 index def1516..0000000 --- a/Example/GradientLoadingBar/ViewController.swift +++ /dev/null @@ -1,113 +0,0 @@ -// -// ViewController.swift -// GradientLoadingBar -// -// Created by fxm90 on 09/30/2017. -// Copyright (c) 2017 fxm90. All rights reserved. -// - -import GradientLoadingBar -import UIKit - -class ViewController: UIViewController { - @IBOutlet var showButton: UIButton! - @IBOutlet var toggleButton: UIButton! - @IBOutlet var hideButton: UIButton! - - @IBOutlet var customSuperviewButton: UIButton! - @IBOutlet var customContraintsButton: UIButton! - - @IBOutlet var navigationBarButton: UIButton! - - var customSuperviewLoadingBar: GradientLoadingBar? - var customConstraintsLoadingBar: BottomGradientLoadingBar? - var navigationLoadingBar: BottomGradientLoadingBar? - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. - - // Style buttons - let basicButtonList = [showButton, toggleButton, hideButton, navigationBarButton] - basicButtonList.forEach { (button: UIButton!) in - button.layer.cornerRadius = 4.0 - button.tintColor = UIColor.white - button.backgroundColor = UIColor.aquaBlue - } - - let customButtonList = [customSuperviewButton, customContraintsButton] - customButtonList.forEach { (button: UIButton!) in - button.layer.borderColor = UIColor.aquaBlue.cgColor - button.layer.borderWidth = 1.0 - button.layer.cornerRadius = 4.0 - - button.tintColor = UIColor.aquaBlue - button.backgroundColor = UIColor.clear - } - - // Add gradient loading bar to button. - customSuperviewLoadingBar = GradientLoadingBar(onView: customSuperviewButton) - customSuperviewButton.clipsToBounds = true - - // Add custom gradient loading bar to button. - customConstraintsLoadingBar = BottomGradientLoadingBar(onView: customContraintsButton) - customContraintsButton.clipsToBounds = true - - // Add custom gradient loading bar to navigation bar - if let navigationBar = navigationController?.navigationBar { - navigationLoadingBar = BottomGradientLoadingBar(onView: navigationBar) - } - } - - // MARK: - User actions - - @IBAction func onShowButtonTouchUpInside(_: Any) { - GradientLoadingBar.shared.show() - } - - @IBAction func onToggleButtonTouchUpInside(_: Any) { - GradientLoadingBar.shared.toggle() - } - - @IBAction func onHideButtonTouchUpInside(_: Any) { - GradientLoadingBar.shared.hide() - } - - @IBAction func onCustomSuperviewButtonTouchUpInside(_: Any) { - guard let customSuperviewLoadingBar = customSuperviewLoadingBar else { return } - - customSuperviewLoadingBar.toggle() - } - - @IBAction func onCustomContraintsButtonTouchUpInside(_: Any) { - guard let customConstraintsLoadingBar = customConstraintsLoadingBar else { return } - - customConstraintsLoadingBar.toggle() - } - - @IBAction func onNavigationBarButtonTouchUpInside(_: Any) { - guard let navigationLoadingBar = navigationLoadingBar else { return } - - navigationLoadingBar.toggle() - } -} - -// MARK: - Custom Gradient Loading Bar - -class BottomGradientLoadingBar: GradientLoadingBar { - override func setupConstraints(superview: UIView) { - NSLayoutConstraint.activate([ - gradientView.leadingAnchor.constraint(equalTo: superview.leadingAnchor), - gradientView.trailingAnchor.constraint(equalTo: superview.trailingAnchor), - - gradientView.bottomAnchor.constraint(equalTo: superview.bottomAnchor), - gradientView.heightAnchor.constraint(equalToConstant: CGFloat(height)) - ]) - } -} - -// MARK: - Helper - -fileprivate extension UIColor { - static let aquaBlue = UIColor(hex: "#4990e2") -} diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 9808bf1..7b2dd4c 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,7 @@ PODS: - - GradientLoadingBar (1.1.11) + - GradientLoadingBar (1.1.11): + - Observable + - Observable (1.3.3) - SwiftFormat/CLI (0.35.2) - SwiftLint (0.27.0) @@ -13,7 +15,8 @@ EXTERNAL SOURCES: :path: ../ SPEC CHECKSUMS: - GradientLoadingBar: d06c05c4732c6a1404d47f33342de8fb3062d5e2 + GradientLoadingBar: ab1b7e3fb70aa3843a4c87fc511c681bac91778f + Observable: 360b0132cef970a50bc69611df7fcbda46e91c34 SwiftFormat: d26c78821785f8c1d029323658c93a977cdf31bf SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073 diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index ff903f4..7b2dd4c 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -20,6 +20,6 @@ SPEC CHECKSUMS: SwiftFormat: d26c78821785f8c1d029323658c93a977cdf31bf SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073 -PODFILE CHECKSUM: cb5da5528bd7a41bec85ae0311fc5e9fc0b96e9c +PODFILE CHECKSUM: 55891446b31c0884d45a4c65f1b52d307ff274bc COCOAPODS: 1.3.1 diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 3ec2150..18a853a 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -7,132 +7,136 @@ objects = { /* Begin PBXBuildFile section */ - 0A24F9CFA5D9A8D086D604E3D2F83840 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D757C4DAB7D299B5B6A9C78D8558897 /* GradientView.swift */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 1B508C3732F51FCEB0F4635A802DADCA /* Pods-GradientLoadingBar_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C7A707D05A1C993F972D63ED341DF2 /* Pods-GradientLoadingBar_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 1BE3FC45282A489B41CADBB91B26597B /* Pods-GradientLoadingBar_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 35F45E13E0437FDF717140CA22C9C52A /* Pods-GradientLoadingBar_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 21099F053678CC07D8C1C5B04346D9A3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5A944939BE5460DEF5F9F4588F9DFF7 /* Foundation.framework */; }; - 263627164E406AFFD95155E173027782 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5A944939BE5460DEF5F9F4588F9DFF7 /* Foundation.framework */; }; - 2DE42A29980B215709D0374B9CDAF864 /* Observable-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AA2687E35F25C441F2E81A536762B2F5 /* Observable-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 3D3CCA6D43E5AE89C0845F773BED920F /* GradientLoadingBar-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 00A137836E31F0B85F44FE7ED28C8A1E /* GradientLoadingBar-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 42C9B868EFF007C954640D7937E4D31F /* Pods-GradientLoadingBar_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C3A7E062B6B3E795C008251C9BD8BA /* Pods-GradientLoadingBar_Example-dummy.m */; }; - 53B37B1A5CD4E5752EC90305BCA9A1E4 /* Durations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 246B489FC979CB11F78FF76AE8B59FE2 /* Durations.swift */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 58DAC4AC2D0F3E54E5BBB5CE6FE6C93D /* GradientLoadingBarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754B7114D4EEDF2BB932C2E3D924F774 /* GradientLoadingBarViewModel.swift */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 6D5912C2DDE4662EB68F4569C645C09B /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 722B62968CEEC329B4F457E386567386 /* Disposable.swift */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 77A0F79C95F0C2561B91D4B5F5C2EED4 /* Observable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C47C72A5BD1CE40555C3CA440845A93E /* Observable.framework */; }; - A2B4EF6ABA56186BAE518466847A0490 /* UIColor+Initializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63D66746F49F8782E7357FA82EF7779D /* UIColor+Initializers.swift */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - A30BEAE852275C391EAEC9E314339EB1 /* GradientLoadingBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06A09E03ECBCBDC050671661FC8AE063 /* GradientLoadingBarController.swift */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - ADBF676850928CD01AAD7CD65CDF91A8 /* GradientLoadingBar-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C47EFA242B2BA62A2408CC13176C080D /* GradientLoadingBar-dummy.m */; }; - B197025B05C5C81BF8345D13849A9C81 /* Pods-GradientLoadingBar_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E81AB562A2ACC55D8595C5C93F545EA7 /* Pods-GradientLoadingBar_Tests-dummy.m */; }; - BA95AAF46D83E99F038F9161921D0FF8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5A944939BE5460DEF5F9F4588F9DFF7 /* Foundation.framework */; }; - E61B45CF190D839749DAB21660A95E78 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5A944939BE5460DEF5F9F4588F9DFF7 /* Foundation.framework */; }; - EA0BC8E6D4AFBEA5C2AD8E065FEF64B8 /* Observable-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 08B7FD7F0ECBFCA1FB3F301D61BF4F2A /* Observable-dummy.m */; }; - F7EC2D3AE7D079C6008BB3D8A140C53F /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C43F7177749CE2D34E637E99D91ADF /* Observable.swift */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 14E34F2FC56CDB341B8CD173401FF66F /* GradientLoadingBarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 754B7114D4EEDF2BB932C2E3D924F774 /* GradientLoadingBarViewModel.swift */; }; + 19F491169D5D7A76C3D583361A5F765E /* Observable-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CF9C904F0858CDFA3AFA72795D139166 /* Observable-dummy.m */; }; + 3BD55B868DB764CCD2E943DE6522C711 /* Pods-GradientLoadingBar_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B611CFC1F8EE4FAEC01581F75425F48F /* Pods-GradientLoadingBar_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 410C32527DA1C36AD0EB1F734DF30F63 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D757C4DAB7D299B5B6A9C78D8558897 /* GradientView.swift */; }; + 41FE926E4A2953011E28E0828D9C4D47 /* Pods-GradientLoadingBar_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BD04847FCD93EA8DB873ED60D7DAFE9 /* Pods-GradientLoadingBar_Tests-dummy.m */; }; + 42700F5C19F84B620D310DDA38358680 /* Pods-GradientLoadingBar_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 82F153091821DD341797CA12A8D4CAE1 /* Pods-GradientLoadingBar_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 42A5BF833E99B4308184BAC0683BB844 /* GradientLoadingBar-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C3DD02551A23555DB276E5C889202410 /* GradientLoadingBar-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 51FD697B3B39906373FCA272F04DBB21 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C43F7177749CE2D34E637E99D91ADF /* Observable.swift */; }; + 55656C05E84FBAA439434628CAE0807C /* Durations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91137801425EC3258DF0A324E7E21479 /* Durations.swift */; }; + 583320F81D5FB0A79AEE966E30726847 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DF6AA5B777CE6872A2AC92643E0F757 /* Foundation.framework */; }; + 58D38BC09745F446AC48F11334057D84 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 722B62968CEEC329B4F457E386567386 /* Disposable.swift */; }; + 59D5281FED73053EB4FC2B7C18BB549A /* GradientLoadingBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06A09E03ECBCBDC050671661FC8AE063 /* GradientLoadingBarController.swift */; }; + 6E44A75E5276817BB08F4F73C2990FFB /* UIColor+Initializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BF45528DA03D1112CBFCB0C3C2CC5D5 /* UIColor+Initializers.swift */; }; + 85AB74790BFEF71ECBF8E4E0E474EE1D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DF6AA5B777CE6872A2AC92643E0F757 /* Foundation.framework */; }; + 8F4564D8D28F3E6B247AC23E5056A66A /* Observable-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3131299175A2E33CBF0F769C12C56D84 /* Observable-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 97DCD2C821329F760063390D /* UIColor+DefaultGradientColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97DCD2C721329F760063390D /* UIColor+DefaultGradientColors.swift */; }; + 97FA5959213184BB00CCD446 /* Observable+ObserveDistinct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97FA5958213184BB00CCD446 /* Observable+ObserveDistinct.swift */; }; + 9FDB4DBD4970F733BC1D1920C105F50D /* Observable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C47C72A5BD1CE40555C3CA440845A93E /* Observable.framework */; }; + AB3A9CC5A95BFB9B88345250A55CB9B2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DF6AA5B777CE6872A2AC92643E0F757 /* Foundation.framework */; }; + C5CDCD73BBA932C6431C08C26F7A3F27 /* GradientLoadingBar-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FAD0086F8B0C17E13326B0E8980BBD99 /* GradientLoadingBar-dummy.m */; }; + D05F2CAFDA528ECC86E05E2713F3D18A /* Pods-GradientLoadingBar_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = EADFB0EFFF6A08CAA2D4588D6C2F0C44 /* Pods-GradientLoadingBar_Example-dummy.m */; }; + F3F8076DA9EAC73A76B9FE9443230FFD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DF6AA5B777CE6872A2AC92643E0F757 /* Foundation.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 11F0ABF401134D6A07D63CBB85302D0B /* PBXContainerItemProxy */ = { + 0C93EAA1ABD99668F20204408933B35E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 6D7DBBC4BB6995891B4D548F93F52286; + remoteGlobalIDString = 1B4557A96F50C37EE5009366B45453B2; remoteInfo = Observable; }; - 9BBDC016F505E44F0E066512798A7A25 /* PBXContainerItemProxy */ = { + 9BCA4EFA4B96155A510D23270C4FCCCA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 2B63880316D7E6A564FC45314A003B39; + remoteGlobalIDString = 29BC83516D9F29C0D714E5CAF9880C36; remoteInfo = GradientLoadingBar; }; - B51DA324BB2D0F54655F1FA7419616A0 /* PBXContainerItemProxy */ = { + A6D751D2F5C50986BC226AD93E23CB05 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 6D7DBBC4BB6995891B4D548F93F52286; + remoteGlobalIDString = 1B4557A96F50C37EE5009366B45453B2; remoteInfo = Observable; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 00A137836E31F0B85F44FE7ED28C8A1E /* GradientLoadingBar-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GradientLoadingBar-umbrella.h"; sourceTree = ""; }; 01C43F7177749CE2D34E637E99D91ADF /* Observable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Observable.swift; path = Observable/Classes/Observable.swift; sourceTree = ""; }; 06A09E03ECBCBDC050671661FC8AE063 /* GradientLoadingBarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GradientLoadingBarController.swift; path = GradientLoadingBar/Classes/GradientLoadingBarController.swift; sourceTree = ""; }; - 08B7FD7F0ECBFCA1FB3F301D61BF4F2A /* Observable-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Observable-dummy.m"; sourceTree = ""; }; - 0F3D57DC040DA67C87298D736812CC57 /* GradientLoadingBar.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = GradientLoadingBar.modulemap; sourceTree = ""; }; - 14091D853C2B706DF1AE856AE9CFCB78 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 17F4D7C8C9BBFFB7EF138F17A231CC6C /* Pods-GradientLoadingBar_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GradientLoadingBar_Example-resources.sh"; sourceTree = ""; }; - 1878BB23EEDD3A204AC30460410579BB /* GradientLoadingBar-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GradientLoadingBar-prefix.pch"; sourceTree = ""; }; - 1B905A25A2D3A59BB8868C53B35A84E3 /* Pods-GradientLoadingBar_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GradientLoadingBar_Example-frameworks.sh"; sourceTree = ""; }; + 1422984811CD4F12D80E9B354599586E /* Pods-GradientLoadingBar_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-GradientLoadingBar_Tests-acknowledgements.markdown"; sourceTree = ""; }; + 1ACAE8D17B2522B64920E9EA81C13EBA /* Pods-GradientLoadingBar_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-GradientLoadingBar_Tests.modulemap"; sourceTree = ""; }; + 1B20B670FBFC9008DFDE45D9D36A94BF /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 1D757C4DAB7D299B5B6A9C78D8558897 /* GradientView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = ""; }; - 22C2A4F9D4B8EA034AC866A1472C25AB /* Pods-GradientLoadingBar_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GradientLoadingBar_Tests-resources.sh"; sourceTree = ""; }; - 246B489FC979CB11F78FF76AE8B59FE2 /* Durations.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Durations.swift; sourceTree = ""; }; - 256932D0EFF124768B7828B4DBB26BB6 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 22AA11253C3E2F00F94AAA627F044BD9 /* GradientLoadingBar.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GradientLoadingBar.xcconfig; sourceTree = ""; }; 284E5B1E5B78675A430CFB3C83D79E8F /* Pods_GradientLoadingBar_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GradientLoadingBar_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 29F34B3709A0B91080A953ED30B6C8F6 /* GradientLoadingBar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GradientLoadingBar.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 32E0246132717AB85B87AD5A70F2E50F /* Pods-GradientLoadingBar_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GradientLoadingBar_Tests-acknowledgements.plist"; sourceTree = ""; }; - 34665263080E033320411F4B5805E2FB /* Observable.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Observable.modulemap; sourceTree = ""; }; - 34E3BE59D6126F5B792C30F96DB73D61 /* Pods-GradientLoadingBar_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GradientLoadingBar_Example-acknowledgements.plist"; sourceTree = ""; }; - 35F45E13E0437FDF717140CA22C9C52A /* Pods-GradientLoadingBar_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-GradientLoadingBar_Tests-umbrella.h"; sourceTree = ""; }; - 4C3D18A136BBE022D715E4F77216A1F0 /* Pods-GradientLoadingBar_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GradientLoadingBar_Example.debug.xcconfig"; sourceTree = ""; }; - 4C6F162952B5A3ED1A168FAE5C81155D /* Pods-GradientLoadingBar_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-GradientLoadingBar_Tests.modulemap"; sourceTree = ""; }; - 501B9AB1C1F1E59F4628E81A7970CD37 /* Pods-GradientLoadingBar_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GradientLoadingBar_Example.release.xcconfig"; sourceTree = ""; }; - 50C7A707D05A1C993F972D63ED341DF2 /* Pods-GradientLoadingBar_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-GradientLoadingBar_Example-umbrella.h"; sourceTree = ""; }; - 53267FC01B3E758EC7BC06C1D2220B74 /* Pods-GradientLoadingBar_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GradientLoadingBar_Tests.release.xcconfig"; sourceTree = ""; }; - 59139AD54A0546CEF68F95C77C8D6708 /* Pods-GradientLoadingBar_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GradientLoadingBar_Tests-frameworks.sh"; sourceTree = ""; }; - 5F2D68AB1D719F1B064D511C976B1ABE /* Pods-GradientLoadingBar_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-GradientLoadingBar_Tests-acknowledgements.markdown"; sourceTree = ""; }; - 62982164F2B5DEF7B82A870F71FBFE74 /* Observable.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Observable.xcconfig; sourceTree = ""; }; - 63D66746F49F8782E7357FA82EF7779D /* UIColor+Initializers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIColor+Initializers.swift"; sourceTree = ""; }; - 6518FD84E10BB5DA39E8C1DB4FB82203 /* Pods-GradientLoadingBar_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-GradientLoadingBar_Example.modulemap"; sourceTree = ""; }; + 2A531589E8C2F7E9E4724BEC2BBFDF40 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2A8296F5F5318573C2FDDBC6C1D3C70E /* Observable.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Observable.modulemap; sourceTree = ""; }; + 2BB9B4AFA01DC30399978F0AFE74FB96 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2F96DBDA2338122C5D2332063A0DDC4B /* Pods-GradientLoadingBar_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GradientLoadingBar_Example.release.xcconfig"; sourceTree = ""; }; + 3131299175A2E33CBF0F769C12C56D84 /* Observable-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Observable-umbrella.h"; sourceTree = ""; }; + 3BF45528DA03D1112CBFCB0C3C2CC5D5 /* UIColor+Initializers.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIColor+Initializers.swift"; sourceTree = ""; }; + 6B955E6ED6F1FC3FAAD1C08036A4E384 /* Pods-GradientLoadingBar_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-GradientLoadingBar_Example-acknowledgements.markdown"; sourceTree = ""; }; + 6BD04847FCD93EA8DB873ED60D7DAFE9 /* Pods-GradientLoadingBar_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-GradientLoadingBar_Tests-dummy.m"; sourceTree = ""; }; 722B62968CEEC329B4F457E386567386 /* Disposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Disposable.swift; path = Observable/Classes/Disposable.swift; sourceTree = ""; }; 754B7114D4EEDF2BB932C2E3D924F774 /* GradientLoadingBarViewModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GradientLoadingBarViewModel.swift; sourceTree = ""; }; - 77280710966B3ABC4F68126D78BA144E /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 91C3A7E062B6B3E795C008251C9BD8BA /* Pods-GradientLoadingBar_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-GradientLoadingBar_Example-dummy.m"; sourceTree = ""; }; + 75C5982942533A2C5C4EB95855F66B17 /* GradientLoadingBar.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GradientLoadingBar.modulemap; sourceTree = ""; }; + 799C8ECAB8385DF70782BAA1ADF9A6F2 /* Observable-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Observable-prefix.pch"; sourceTree = ""; }; + 82F153091821DD341797CA12A8D4CAE1 /* Pods-GradientLoadingBar_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-GradientLoadingBar_Tests-umbrella.h"; sourceTree = ""; }; + 833F0F13D70DBDC5C2103FB7B32A4551 /* Pods-GradientLoadingBar_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GradientLoadingBar_Tests-resources.sh"; sourceTree = ""; }; + 8DF6AA5B777CE6872A2AC92643E0F757 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 91137801425EC3258DF0A324E7E21479 /* Durations.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Durations.swift; sourceTree = ""; }; 92A830507050E1BD2B0BDFF09D9D3B54 /* Observable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Observable.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 94987193A3C956E52823A639B1A63FE9 /* Pods_GradientLoadingBar_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GradientLoadingBar_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - AA2687E35F25C441F2E81A536762B2F5 /* Observable-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Observable-umbrella.h"; sourceTree = ""; }; - AE41E5BEBBA1125468690FAAE3B7E176 /* Pods-GradientLoadingBar_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-GradientLoadingBar_Example-acknowledgements.markdown"; sourceTree = ""; }; - AE81FE3F50CEA8E993C3DC8F5A9989B8 /* Pods-GradientLoadingBar_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GradientLoadingBar_Tests.debug.xcconfig"; sourceTree = ""; }; - B4E51896180DEC5DBCEC4A155254A5B7 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - BF697EEBEEA924D759152FB1E68358EA /* Observable-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Observable-prefix.pch"; sourceTree = ""; }; + 97DCD2C721329F760063390D /* UIColor+DefaultGradientColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+DefaultGradientColors.swift"; sourceTree = ""; }; + 97FA5958213184BB00CCD446 /* Observable+ObserveDistinct.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+ObserveDistinct.swift"; sourceTree = ""; }; + 9A04D73ADF1F86BA48555BCA8C37357F /* Pods-GradientLoadingBar_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GradientLoadingBar_Tests-acknowledgements.plist"; sourceTree = ""; }; + 9AC0D5BE1D3E0BD55B9098C545D90E0E /* Observable.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Observable.xcconfig; sourceTree = ""; }; + A7EE3290A69260383C55CBE340D72011 /* Pods-GradientLoadingBar_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GradientLoadingBar_Tests.debug.xcconfig"; sourceTree = ""; }; + AA412B257C4E7111197588A95B11802A /* Pods-GradientLoadingBar_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-GradientLoadingBar_Example.modulemap"; sourceTree = ""; }; + B611CFC1F8EE4FAEC01581F75425F48F /* Pods-GradientLoadingBar_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-GradientLoadingBar_Example-umbrella.h"; sourceTree = ""; }; + C3DD02551A23555DB276E5C889202410 /* GradientLoadingBar-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GradientLoadingBar-umbrella.h"; sourceTree = ""; }; C47C72A5BD1CE40555C3CA440845A93E /* Observable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Observable.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C47EFA242B2BA62A2408CC13176C080D /* GradientLoadingBar-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GradientLoadingBar-dummy.m"; sourceTree = ""; }; - C5A944939BE5460DEF5F9F4588F9DFF7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - CCC1BC5CEB1151E0A04A33B26AE57411 /* GradientLoadingBar.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GradientLoadingBar.xcconfig; sourceTree = ""; }; - E81AB562A2ACC55D8595C5C93F545EA7 /* Pods-GradientLoadingBar_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-GradientLoadingBar_Tests-dummy.m"; sourceTree = ""; }; + C9A69D64E3CB45E450A0A9A578B867B1 /* GradientLoadingBar-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "GradientLoadingBar-prefix.pch"; sourceTree = ""; }; + CF9C904F0858CDFA3AFA72795D139166 /* Observable-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Observable-dummy.m"; sourceTree = ""; }; + D1B3EBFC292193F84BD5C4C3A34B09A1 /* Pods-GradientLoadingBar_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GradientLoadingBar_Example-resources.sh"; sourceTree = ""; }; + D5977AF0FD89C99333D17D9288C45267 /* Pods-GradientLoadingBar_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GradientLoadingBar_Tests-frameworks.sh"; sourceTree = ""; }; + D9DE45D95CCA0E5D76226B173898C17B /* Pods-GradientLoadingBar_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GradientLoadingBar_Tests.release.xcconfig"; sourceTree = ""; }; + E2E8B226D43266B87011381F86DE1C82 /* Pods-GradientLoadingBar_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GradientLoadingBar_Example-acknowledgements.plist"; sourceTree = ""; }; + E38BA62D05FF76C025CDBDB59DF741BB /* Pods-GradientLoadingBar_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GradientLoadingBar_Example-frameworks.sh"; sourceTree = ""; }; + EADFB0EFFF6A08CAA2D4588D6C2F0C44 /* Pods-GradientLoadingBar_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-GradientLoadingBar_Example-dummy.m"; sourceTree = ""; }; + EDF962C570BB30FE0D9F48B3D7F9A90A /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F0F91F53502405804E4AFA6E2F5FF2A8 /* Pods-GradientLoadingBar_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GradientLoadingBar_Example.debug.xcconfig"; sourceTree = ""; }; + FAD0086F8B0C17E13326B0E8980BBD99 /* GradientLoadingBar-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "GradientLoadingBar-dummy.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 59F37F7D8B605E50951D3B44E3346680 /* Frameworks */ = { + 5D645B329A93EDD2A3CA49E6D094D9D7 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E61B45CF190D839749DAB21660A95E78 /* Foundation.framework in Frameworks */, + 85AB74790BFEF71ECBF8E4E0E474EE1D /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - B217AC9E2BED077FE57913D6F7FA922D /* Frameworks */ = { + B55473D3F1732C74E6FF23E04945B768 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 263627164E406AFFD95155E173027782 /* Foundation.framework in Frameworks */, - 77A0F79C95F0C2561B91D4B5F5C2EED4 /* Observable.framework in Frameworks */, + AB3A9CC5A95BFB9B88345250A55CB9B2 /* Foundation.framework in Frameworks */, + 9FDB4DBD4970F733BC1D1920C105F50D /* Observable.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - B8F019218DBFA9F8332F0920CA8CC9B7 /* Frameworks */ = { + BD7DAE274BD59408E3C217FD879EA1B1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 21099F053678CC07D8C1C5B04346D9A3 /* Foundation.framework in Frameworks */, + F3F8076DA9EAC73A76B9FE9443230FFD /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - F647AA8CBE0A1F1C353CFA2CB5B2AB2E /* Frameworks */ = { + D2A4EF1259F904762E08BC447A5DE5B6 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BA95AAF46D83E99F038F9161921D0FF8 /* Foundation.framework in Frameworks */, + 583320F81D5FB0A79AEE966E30726847 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -144,7 +148,7 @@ children = ( 722B62968CEEC329B4F457E386567386 /* Disposable.swift */, 01C43F7177749CE2D34E637E99D91ADF /* Observable.swift */, - D14DA957BF229DC52113DDB438027DC5 /* Support Files */, + B9A3C301A18A8AC0473E69E97CAB7736 /* Support Files */, ); path = Observable; sourceTree = ""; @@ -165,14 +169,18 @@ path = SwiftLint; sourceTree = ""; }; - 1B4DA3251E5BE2DF50EBFA48751BC9B9 /* Helpers */ = { + 1BA5227236DF21EEF1E76FB43C7CA971 /* Support Files */ = { isa = PBXGroup; children = ( - 5E53040C37E18BA3B646FACB44A8F5F1 /* Extensions */, - DC7FD9A01C467AB3B493793994163D68 /* Structs */, + 75C5982942533A2C5C4EB95855F66B17 /* GradientLoadingBar.modulemap */, + 22AA11253C3E2F00F94AAA627F044BD9 /* GradientLoadingBar.xcconfig */, + FAD0086F8B0C17E13326B0E8980BBD99 /* GradientLoadingBar-dummy.m */, + C9A69D64E3CB45E450A0A9A578B867B1 /* GradientLoadingBar-prefix.pch */, + C3DD02551A23555DB276E5C889202410 /* GradientLoadingBar-umbrella.h */, + 2A531589E8C2F7E9E4724BEC2BBFDF40 /* Info.plist */, ); - name = Helpers; - path = GradientLoadingBar/Classes/Helpers; + name = "Support Files"; + path = "Example/Pods/Target Support Files/GradientLoadingBar"; sourceTree = ""; }; 20E70D97A2915DA6914F9C107FDBBE1E /* Products */ = { @@ -186,50 +194,29 @@ name = Products; sourceTree = ""; }; - 46CFB12F74039FE17BF676EE34443260 /* iOS */ = { + 2F5986BA41C59FC4798632C728EEE280 /* Pods-GradientLoadingBar_Tests */ = { isa = PBXGroup; children = ( - C5A944939BE5460DEF5F9F4588F9DFF7 /* Foundation.framework */, + 2BB9B4AFA01DC30399978F0AFE74FB96 /* Info.plist */, + 1ACAE8D17B2522B64920E9EA81C13EBA /* Pods-GradientLoadingBar_Tests.modulemap */, + 1422984811CD4F12D80E9B354599586E /* Pods-GradientLoadingBar_Tests-acknowledgements.markdown */, + 9A04D73ADF1F86BA48555BCA8C37357F /* Pods-GradientLoadingBar_Tests-acknowledgements.plist */, + 6BD04847FCD93EA8DB873ED60D7DAFE9 /* Pods-GradientLoadingBar_Tests-dummy.m */, + D5977AF0FD89C99333D17D9288C45267 /* Pods-GradientLoadingBar_Tests-frameworks.sh */, + 833F0F13D70DBDC5C2103FB7B32A4551 /* Pods-GradientLoadingBar_Tests-resources.sh */, + 82F153091821DD341797CA12A8D4CAE1 /* Pods-GradientLoadingBar_Tests-umbrella.h */, + A7EE3290A69260383C55CBE340D72011 /* Pods-GradientLoadingBar_Tests.debug.xcconfig */, + D9DE45D95CCA0E5D76226B173898C17B /* Pods-GradientLoadingBar_Tests.release.xcconfig */, ); - name = iOS; + name = "Pods-GradientLoadingBar_Tests"; + path = "Target Support Files/Pods-GradientLoadingBar_Tests"; sourceTree = ""; }; - 4AC9178D9814BACA9FE9E7A77F04973D /* Support Files */ = { + 5B86B3E4B046CE8CEE7CB92D250BF78D /* Extensions */ = { isa = PBXGroup; children = ( - 0F3D57DC040DA67C87298D736812CC57 /* GradientLoadingBar.modulemap */, - CCC1BC5CEB1151E0A04A33B26AE57411 /* GradientLoadingBar.xcconfig */, - C47EFA242B2BA62A2408CC13176C080D /* GradientLoadingBar-dummy.m */, - 1878BB23EEDD3A204AC30460410579BB /* GradientLoadingBar-prefix.pch */, - 00A137836E31F0B85F44FE7ED28C8A1E /* GradientLoadingBar-umbrella.h */, - 77280710966B3ABC4F68126D78BA144E /* Info.plist */, - ); - name = "Support Files"; - path = "Example/Pods/Target Support Files/GradientLoadingBar"; - sourceTree = ""; - }; - 5B9E84DCD3E3A5647594EEBFF0F5B00A /* Pods-GradientLoadingBar_Example */ = { - isa = PBXGroup; - children = ( - 14091D853C2B706DF1AE856AE9CFCB78 /* Info.plist */, - 6518FD84E10BB5DA39E8C1DB4FB82203 /* Pods-GradientLoadingBar_Example.modulemap */, - AE41E5BEBBA1125468690FAAE3B7E176 /* Pods-GradientLoadingBar_Example-acknowledgements.markdown */, - 34E3BE59D6126F5B792C30F96DB73D61 /* Pods-GradientLoadingBar_Example-acknowledgements.plist */, - 91C3A7E062B6B3E795C008251C9BD8BA /* Pods-GradientLoadingBar_Example-dummy.m */, - 1B905A25A2D3A59BB8868C53B35A84E3 /* Pods-GradientLoadingBar_Example-frameworks.sh */, - 17F4D7C8C9BBFFB7EF138F17A231CC6C /* Pods-GradientLoadingBar_Example-resources.sh */, - 50C7A707D05A1C993F972D63ED341DF2 /* Pods-GradientLoadingBar_Example-umbrella.h */, - 4C3D18A136BBE022D715E4F77216A1F0 /* Pods-GradientLoadingBar_Example.debug.xcconfig */, - 501B9AB1C1F1E59F4628E81A7970CD37 /* Pods-GradientLoadingBar_Example.release.xcconfig */, - ); - name = "Pods-GradientLoadingBar_Example"; - path = "Target Support Files/Pods-GradientLoadingBar_Example"; - sourceTree = ""; - }; - 5E53040C37E18BA3B646FACB44A8F5F1 /* Extensions */ = { - isa = PBXGroup; - children = ( - 63D66746F49F8782E7357FA82EF7779D /* UIColor+Initializers.swift */, + 97DCD2C621329F5D0063390D /* UIColor */, + 97FA5958213184BB00CCD446 /* Observable+ObserveDistinct.swift */, ); path = Extensions; sourceTree = ""; @@ -268,8 +255,8 @@ 89EC43461F8350C8C85CBAA922CE7FC3 /* Targets Support Files */ = { isa = PBXGroup; children = ( - 5B9E84DCD3E3A5647594EEBFF0F5B00A /* Pods-GradientLoadingBar_Example */, - C618633350DBB1327D211DE794417A1F /* Pods-GradientLoadingBar_Tests */, + D78297D5D15B07F65F5BE3EFB324B611 /* Pods-GradientLoadingBar_Example */, + 2F5986BA41C59FC4798632C728EEE280 /* Pods-GradientLoadingBar_Tests */, ); name = "Targets Support Files"; sourceTree = ""; @@ -282,33 +269,40 @@ name = "Development Pods"; sourceTree = ""; }; - C618633350DBB1327D211DE794417A1F /* Pods-GradientLoadingBar_Tests */ = { + 91E52B6A4D0399DEC177B4245278E3EB /* iOS */ = { isa = PBXGroup; children = ( - B4E51896180DEC5DBCEC4A155254A5B7 /* Info.plist */, - 4C6F162952B5A3ED1A168FAE5C81155D /* Pods-GradientLoadingBar_Tests.modulemap */, - 5F2D68AB1D719F1B064D511C976B1ABE /* Pods-GradientLoadingBar_Tests-acknowledgements.markdown */, - 32E0246132717AB85B87AD5A70F2E50F /* Pods-GradientLoadingBar_Tests-acknowledgements.plist */, - E81AB562A2ACC55D8595C5C93F545EA7 /* Pods-GradientLoadingBar_Tests-dummy.m */, - 59139AD54A0546CEF68F95C77C8D6708 /* Pods-GradientLoadingBar_Tests-frameworks.sh */, - 22C2A4F9D4B8EA034AC866A1472C25AB /* Pods-GradientLoadingBar_Tests-resources.sh */, - 35F45E13E0437FDF717140CA22C9C52A /* Pods-GradientLoadingBar_Tests-umbrella.h */, - AE81FE3F50CEA8E993C3DC8F5A9989B8 /* Pods-GradientLoadingBar_Tests.debug.xcconfig */, - 53267FC01B3E758EC7BC06C1D2220B74 /* Pods-GradientLoadingBar_Tests.release.xcconfig */, + 8DF6AA5B777CE6872A2AC92643E0F757 /* Foundation.framework */, ); - name = "Pods-GradientLoadingBar_Tests"; - path = "Target Support Files/Pods-GradientLoadingBar_Tests"; + name = iOS; sourceTree = ""; }; - D14DA957BF229DC52113DDB438027DC5 /* Support Files */ = { + 97DCD2C621329F5D0063390D /* UIColor */ = { isa = PBXGroup; children = ( - 256932D0EFF124768B7828B4DBB26BB6 /* Info.plist */, - 34665263080E033320411F4B5805E2FB /* Observable.modulemap */, - 62982164F2B5DEF7B82A870F71FBFE74 /* Observable.xcconfig */, - 08B7FD7F0ECBFCA1FB3F301D61BF4F2A /* Observable-dummy.m */, - BF697EEBEEA924D759152FB1E68358EA /* Observable-prefix.pch */, - AA2687E35F25C441F2E81A536762B2F5 /* Observable-umbrella.h */, + 3BF45528DA03D1112CBFCB0C3C2CC5D5 /* UIColor+Initializers.swift */, + 97DCD2C721329F760063390D /* UIColor+DefaultGradientColors.swift */, + ); + path = UIColor; + sourceTree = ""; + }; + B17F5509E43F875711A13CD2968D398C /* Structs */ = { + isa = PBXGroup; + children = ( + 91137801425EC3258DF0A324E7E21479 /* Durations.swift */, + ); + path = Structs; + sourceTree = ""; + }; + B9A3C301A18A8AC0473E69E97CAB7736 /* Support Files */ = { + isa = PBXGroup; + children = ( + EDF962C570BB30FE0D9F48B3D7F9A90A /* Info.plist */, + 2A8296F5F5318573C2FDDBC6C1D3C70E /* Observable.modulemap */, + 9AC0D5BE1D3E0BD55B9098C545D90E0E /* Observable.xcconfig */, + CF9C904F0858CDFA3AFA72795D139166 /* Observable-dummy.m */, + 799C8ECAB8385DF70782BAA1ADF9A6F2 /* Observable-prefix.pch */, + 3131299175A2E33CBF0F769C12C56D84 /* Observable-umbrella.h */, ); name = "Support Files"; path = "../Target Support Files/Observable"; @@ -318,17 +312,27 @@ isa = PBXGroup; children = ( C47C72A5BD1CE40555C3CA440845A93E /* Observable.framework */, - 46CFB12F74039FE17BF676EE34443260 /* iOS */, + 91E52B6A4D0399DEC177B4245278E3EB /* iOS */, ); name = Frameworks; sourceTree = ""; }; - DC7FD9A01C467AB3B493793994163D68 /* Structs */ = { + D78297D5D15B07F65F5BE3EFB324B611 /* Pods-GradientLoadingBar_Example */ = { isa = PBXGroup; children = ( - 246B489FC979CB11F78FF76AE8B59FE2 /* Durations.swift */, + 1B20B670FBFC9008DFDE45D9D36A94BF /* Info.plist */, + AA412B257C4E7111197588A95B11802A /* Pods-GradientLoadingBar_Example.modulemap */, + 6B955E6ED6F1FC3FAAD1C08036A4E384 /* Pods-GradientLoadingBar_Example-acknowledgements.markdown */, + E2E8B226D43266B87011381F86DE1C82 /* Pods-GradientLoadingBar_Example-acknowledgements.plist */, + EADFB0EFFF6A08CAA2D4588D6C2F0C44 /* Pods-GradientLoadingBar_Example-dummy.m */, + E38BA62D05FF76C025CDBDB59DF741BB /* Pods-GradientLoadingBar_Example-frameworks.sh */, + D1B3EBFC292193F84BD5C4C3A34B09A1 /* Pods-GradientLoadingBar_Example-resources.sh */, + B611CFC1F8EE4FAEC01581F75425F48F /* Pods-GradientLoadingBar_Example-umbrella.h */, + F0F91F53502405804E4AFA6E2F5FF2A8 /* Pods-GradientLoadingBar_Example.debug.xcconfig */, + 2F96DBDA2338122C5D2332063A0DDC4B /* Pods-GradientLoadingBar_Example.release.xcconfig */, ); - path = Structs; + name = "Pods-GradientLoadingBar_Example"; + path = "Target Support Files/Pods-GradientLoadingBar_Example"; sourceTree = ""; }; E00683E90061990C87DF25B5810284BB /* SwiftFormat */ = { @@ -342,8 +346,9 @@ isa = PBXGroup; children = ( 06A09E03ECBCBDC050671661FC8AE063 /* GradientLoadingBarController.swift */, - 1B4DA3251E5BE2DF50EBFA48751BC9B9 /* Helpers */, - 4AC9178D9814BACA9FE9E7A77F04973D /* Support Files */, + 5B86B3E4B046CE8CEE7CB92D250BF78D /* Extensions */, + B17F5509E43F875711A13CD2968D398C /* Structs */, + 1BA5227236DF21EEF1E76FB43C7CA971 /* Support Files */, 8403B26617BC5720B6F7AFBB72852C26 /* ViewModel */, 03FE9A8BF388CAA1FCEA89FEFEDC42CA /* Views */, ); @@ -354,83 +359,49 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 2A3519C597CAFBF6C661E70C07E4F9C6 /* Headers */ = { + 020552841CAD9616C6F108C7DDA653E4 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 3D3CCA6D43E5AE89C0845F773BED920F /* GradientLoadingBar-umbrella.h in Headers */, + 42A5BF833E99B4308184BAC0683BB844 /* GradientLoadingBar-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5E91C05C0FA2EC76430171501C458770 /* Headers */ = { + 6AD2175A80A812DA862C4B02BE1A91EC /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 1BE3FC45282A489B41CADBB91B26597B /* Pods-GradientLoadingBar_Tests-umbrella.h in Headers */, + 3BD55B868DB764CCD2E943DE6522C711 /* Pods-GradientLoadingBar_Example-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - E45FB182CB503AA3F930BC401966B247 /* Headers */ = { + 9B17BD85DCD21BEDF5D38E04125EAD06 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 1B508C3732F51FCEB0F4635A802DADCA /* Pods-GradientLoadingBar_Example-umbrella.h in Headers */, + 8F4564D8D28F3E6B247AC23E5056A66A /* Observable-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - FB3204964DA0E9693C894666218B8BAA /* Headers */ = { + BAAB2DD73D11B10930D83170C07910E3 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 2DE42A29980B215709D0374B9CDAF864 /* Observable-umbrella.h in Headers */, + 42700F5C19F84B620D310DDA38358680 /* Pods-GradientLoadingBar_Tests-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 0DDE9A7CA243FF8773CE97E05871E530 /* Pods-GradientLoadingBar_Tests */ = { + 1B4557A96F50C37EE5009366B45453B2 /* Observable */ = { isa = PBXNativeTarget; - buildConfigurationList = 769F26B1F11CC0AB6BE2AE773FF66E01 /* Build configuration list for PBXNativeTarget "Pods-GradientLoadingBar_Tests" */; + buildConfigurationList = 994EE5A58AF8B36DD55E52C1787AD1DD /* Build configuration list for PBXNativeTarget "Observable" */; buildPhases = ( - 7C7895461F82DE790DC7F478F1204306 /* Sources */, - B8F019218DBFA9F8332F0920CA8CC9B7 /* Frameworks */, - 5E91C05C0FA2EC76430171501C458770 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "Pods-GradientLoadingBar_Tests"; - productName = "Pods-GradientLoadingBar_Tests"; - productReference = 94987193A3C956E52823A639B1A63FE9 /* Pods_GradientLoadingBar_Tests.framework */; - productType = "com.apple.product-type.framework"; - }; - 2B63880316D7E6A564FC45314A003B39 /* GradientLoadingBar */ = { - isa = PBXNativeTarget; - buildConfigurationList = 37515D7500C740E1F892D462242EE790 /* Build configuration list for PBXNativeTarget "GradientLoadingBar" */; - buildPhases = ( - C47DF8F5CAE3C2D6102D0EDA7329B0A5 /* Sources */, - B217AC9E2BED077FE57913D6F7FA922D /* Frameworks */, - 2A3519C597CAFBF6C661E70C07E4F9C6 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - B92FAD085B6E660E09702054FD94753F /* PBXTargetDependency */, - ); - name = GradientLoadingBar; - productName = GradientLoadingBar; - productReference = 29F34B3709A0B91080A953ED30B6C8F6 /* GradientLoadingBar.framework */; - productType = "com.apple.product-type.framework"; - }; - 6D7DBBC4BB6995891B4D548F93F52286 /* Observable */ = { - isa = PBXNativeTarget; - buildConfigurationList = 00E38063FE1C1ED092C80D09810F4D14 /* Build configuration list for PBXNativeTarget "Observable" */; - buildPhases = ( - FC8393BA9581130F79E1DAD4E4E99763 /* Sources */, - 59F37F7D8B605E50951D3B44E3346680 /* Frameworks */, - FB3204964DA0E9693C894666218B8BAA /* Headers */, + 9B17BD85DCD21BEDF5D38E04125EAD06 /* Headers */, + 8EA26E87E8F728A5B4A7514EE20CCC08 /* Sources */, + 5D645B329A93EDD2A3CA49E6D094D9D7 /* Frameworks */, + C28982422E43BC29FB9E6DD9D172B4C2 /* Resources */, ); buildRules = ( ); @@ -441,19 +412,57 @@ productReference = 92A830507050E1BD2B0BDFF09D9D3B54 /* Observable.framework */; productType = "com.apple.product-type.framework"; }; - C9E360AE7E621FF686F7C060178481D1 /* Pods-GradientLoadingBar_Example */ = { + 29BC83516D9F29C0D714E5CAF9880C36 /* GradientLoadingBar */ = { isa = PBXNativeTarget; - buildConfigurationList = CE51B32DA3B3093FF3BA59642B6C54A8 /* Build configuration list for PBXNativeTarget "Pods-GradientLoadingBar_Example" */; + buildConfigurationList = D104056D84CD79BDB5002659695AC7FB /* Build configuration list for PBXNativeTarget "GradientLoadingBar" */; buildPhases = ( - 652F4121229E4DEADA081DDBD3ED8583 /* Sources */, - F647AA8CBE0A1F1C353CFA2CB5B2AB2E /* Frameworks */, - E45FB182CB503AA3F930BC401966B247 /* Headers */, + 020552841CAD9616C6F108C7DDA653E4 /* Headers */, + B7D13CDC491AB0F30F4D7AE35A5510D8 /* Sources */, + B55473D3F1732C74E6FF23E04945B768 /* Frameworks */, + 4EF358D9C0876239BAD9BCE3B8EA0BB7 /* Resources */, ); buildRules = ( ); dependencies = ( - F0D652528A64CFF6B7D836DAAA8C7AEE /* PBXTargetDependency */, - 8F53C1FF4329F6085BB69BF395E65785 /* PBXTargetDependency */, + 145ABAB33E35774F0F3129FF078F2988 /* PBXTargetDependency */, + ); + name = GradientLoadingBar; + productName = GradientLoadingBar; + productReference = 29F34B3709A0B91080A953ED30B6C8F6 /* GradientLoadingBar.framework */; + productType = "com.apple.product-type.framework"; + }; + 9D42E4BDBAC963058ACB7E9BFBABAA71 /* Pods-GradientLoadingBar_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = FC7BD56761426B5F94E35E60E95CBA50 /* Build configuration list for PBXNativeTarget "Pods-GradientLoadingBar_Tests" */; + buildPhases = ( + BAAB2DD73D11B10930D83170C07910E3 /* Headers */, + 073D260DB926462CE6874413F6BD144C /* Sources */, + D2A4EF1259F904762E08BC447A5DE5B6 /* Frameworks */, + 2ECBDF9FF13C8D2A193090D7316226EE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Pods-GradientLoadingBar_Tests"; + productName = "Pods-GradientLoadingBar_Tests"; + productReference = 94987193A3C956E52823A639B1A63FE9 /* Pods_GradientLoadingBar_Tests.framework */; + productType = "com.apple.product-type.framework"; + }; + F4D39355B29826360A572EE3C73331E9 /* Pods-GradientLoadingBar_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = B3073FF85CC042B5C8BF8C85D5503C1E /* Build configuration list for PBXNativeTarget "Pods-GradientLoadingBar_Example" */; + buildPhases = ( + 6AD2175A80A812DA862C4B02BE1A91EC /* Headers */, + C7919E2E88E9D84627A984B23209EBBF /* Sources */, + BD7DAE274BD59408E3C217FD879EA1B1 /* Frameworks */, + BD78764497D6D39615357FE9AF4D3A11 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8FEFE449390B7AA7B0E1F2F975B8D8AF /* PBXTargetDependency */, + B34F64432C2628511F768F271DC8BEBB /* PBXTargetDependency */, ); name = "Pods-GradientLoadingBar_Example"; productName = "Pods-GradientLoadingBar_Example"; @@ -466,7 +475,7 @@ D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0830; + LastSwiftUpdateCheck = 0930; LastUpgradeCheck = 1000; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; @@ -481,81 +490,114 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 2B63880316D7E6A564FC45314A003B39 /* GradientLoadingBar */, - 6D7DBBC4BB6995891B4D548F93F52286 /* Observable */, - C9E360AE7E621FF686F7C060178481D1 /* Pods-GradientLoadingBar_Example */, - 0DDE9A7CA243FF8773CE97E05871E530 /* Pods-GradientLoadingBar_Tests */, + 29BC83516D9F29C0D714E5CAF9880C36 /* GradientLoadingBar */, + 1B4557A96F50C37EE5009366B45453B2 /* Observable */, + F4D39355B29826360A572EE3C73331E9 /* Pods-GradientLoadingBar_Example */, + 9D42E4BDBAC963058ACB7E9BFBABAA71 /* Pods-GradientLoadingBar_Tests */, ); }; /* End PBXProject section */ +/* Begin PBXResourcesBuildPhase section */ + 2ECBDF9FF13C8D2A193090D7316226EE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4EF358D9C0876239BAD9BCE3B8EA0BB7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BD78764497D6D39615357FE9AF4D3A11 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C28982422E43BC29FB9E6DD9D172B4C2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ - 652F4121229E4DEADA081DDBD3ED8583 /* Sources */ = { + 073D260DB926462CE6874413F6BD144C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 42C9B868EFF007C954640D7937E4D31F /* Pods-GradientLoadingBar_Example-dummy.m in Sources */, + 41FE926E4A2953011E28E0828D9C4D47 /* Pods-GradientLoadingBar_Tests-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 7C7895461F82DE790DC7F478F1204306 /* Sources */ = { + 8EA26E87E8F728A5B4A7514EE20CCC08 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B197025B05C5C81BF8345D13849A9C81 /* Pods-GradientLoadingBar_Tests-dummy.m in Sources */, + 58D38BC09745F446AC48F11334057D84 /* Disposable.swift in Sources */, + 19F491169D5D7A76C3D583361A5F765E /* Observable-dummy.m in Sources */, + 51FD697B3B39906373FCA272F04DBB21 /* Observable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C47DF8F5CAE3C2D6102D0EDA7329B0A5 /* Sources */ = { + B7D13CDC491AB0F30F4D7AE35A5510D8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 53B37B1A5CD4E5752EC90305BCA9A1E4 /* Durations.swift in Sources */, - ADBF676850928CD01AAD7CD65CDF91A8 /* GradientLoadingBar-dummy.m in Sources */, - A30BEAE852275C391EAEC9E314339EB1 /* GradientLoadingBarController.swift in Sources */, - 58DAC4AC2D0F3E54E5BBB5CE6FE6C93D /* GradientLoadingBarViewModel.swift in Sources */, - 0A24F9CFA5D9A8D086D604E3D2F83840 /* GradientView.swift in Sources */, - A2B4EF6ABA56186BAE518466847A0490 /* UIColor+Initializers.swift in Sources */, + 55656C05E84FBAA439434628CAE0807C /* Durations.swift in Sources */, + C5CDCD73BBA932C6431C08C26F7A3F27 /* GradientLoadingBar-dummy.m in Sources */, + 59D5281FED73053EB4FC2B7C18BB549A /* GradientLoadingBarController.swift in Sources */, + 97DCD2C821329F760063390D /* UIColor+DefaultGradientColors.swift in Sources */, + 14E34F2FC56CDB341B8CD173401FF66F /* GradientLoadingBarViewModel.swift in Sources */, + 97FA5959213184BB00CCD446 /* Observable+ObserveDistinct.swift in Sources */, + 410C32527DA1C36AD0EB1F734DF30F63 /* GradientView.swift in Sources */, + 6E44A75E5276817BB08F4F73C2990FFB /* UIColor+Initializers.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - FC8393BA9581130F79E1DAD4E4E99763 /* Sources */ = { + C7919E2E88E9D84627A984B23209EBBF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6D5912C2DDE4662EB68F4569C645C09B /* Disposable.swift in Sources */, - EA0BC8E6D4AFBEA5C2AD8E065FEF64B8 /* Observable-dummy.m in Sources */, - F7EC2D3AE7D079C6008BB3D8A140C53F /* Observable.swift in Sources */, + D05F2CAFDA528ECC86E05E2713F3D18A /* Pods-GradientLoadingBar_Example-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 8F53C1FF4329F6085BB69BF395E65785 /* PBXTargetDependency */ = { + 145ABAB33E35774F0F3129FF078F2988 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Observable; - target = 6D7DBBC4BB6995891B4D548F93F52286 /* Observable */; - targetProxy = 11F0ABF401134D6A07D63CBB85302D0B /* PBXContainerItemProxy */; + target = 1B4557A96F50C37EE5009366B45453B2 /* Observable */; + targetProxy = 0C93EAA1ABD99668F20204408933B35E /* PBXContainerItemProxy */; }; - B92FAD085B6E660E09702054FD94753F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Observable; - target = 6D7DBBC4BB6995891B4D548F93F52286 /* Observable */; - targetProxy = B51DA324BB2D0F54655F1FA7419616A0 /* PBXContainerItemProxy */; - }; - F0D652528A64CFF6B7D836DAAA8C7AEE /* PBXTargetDependency */ = { + 8FEFE449390B7AA7B0E1F2F975B8D8AF /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = GradientLoadingBar; - target = 2B63880316D7E6A564FC45314A003B39 /* GradientLoadingBar */; - targetProxy = 9BBDC016F505E44F0E066512798A7A25 /* PBXContainerItemProxy */; + target = 29BC83516D9F29C0D714E5CAF9880C36 /* GradientLoadingBar */; + targetProxy = 9BCA4EFA4B96155A510D23270C4FCCCA /* PBXContainerItemProxy */; + }; + B34F64432C2628511F768F271DC8BEBB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Observable; + target = 1B4557A96F50C37EE5009366B45453B2 /* Observable */; + targetProxy = A6D751D2F5C50986BC226AD93E23CB05 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 1154D18835E11DCF4C6D3ABBD94FC8B2 /* Debug */ = { + 23B2E1163053F92E823AD3DAAE8AB4AF /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4C3D18A136BBE022D715E4F77216A1F0 /* Pods-GradientLoadingBar_Example.debug.xcconfig */; + baseConfigurationReference = 9AC0D5BE1D3E0BD55B9098C545D90E0E /* Observable.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -566,79 +608,13 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-GradientLoadingBar_Example/Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/Observable/Observable-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Observable/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_GradientLoadingBar_Example; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 2391AB0DF476D0BF15DA502FD5D56E68 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AE81FE3F50CEA8E993C3DC8F5A9989B8 /* Pods-GradientLoadingBar_Tests.debug.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-GradientLoadingBar_Tests/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-GradientLoadingBar_Tests/Pods-GradientLoadingBar_Tests.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_GradientLoadingBar_Tests; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 5C79A6E75624EAA3969DA7A663BBA669 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = CCC1BC5CEB1151E0A04A33B26AE57411 /* GradientLoadingBar.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/GradientLoadingBar/GradientLoadingBar-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/GradientLoadingBar/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/GradientLoadingBar/GradientLoadingBar.modulemap"; - PRODUCT_NAME = GradientLoadingBar; + MODULEMAP_FILE = "Target Support Files/Observable/Observable.modulemap"; + PRODUCT_NAME = Observable; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; @@ -650,7 +626,7 @@ }; name = Debug; }; - 6F9224530522DD3C735EC96CF142642E /* Release */ = { + 798F283DEF5D6E82C13E1DBA995AA1B8 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -660,6 +636,7 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -694,13 +671,13 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_INHIBIT_ALL_WARNINGS = NO; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; @@ -709,9 +686,43 @@ }; name = Release; }; - 7BC683054BF52690B352E993FC6649C1 /* Release */ = { + 7A4149B63F94A67C1FFDB91CA24D7781 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CCC1BC5CEB1151E0A04A33B26AE57411 /* GradientLoadingBar.xcconfig */; + baseConfigurationReference = 2F96DBDA2338122C5D2332063A0DDC4B /* Pods-GradientLoadingBar_Example.release.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-GradientLoadingBar_Example/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_GradientLoadingBar_Example; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + A8BA56DA06DF9659C35399F99D7564CC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 22AA11253C3E2F00F94AAA627F044BD9 /* GradientLoadingBar.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -741,9 +752,43 @@ }; name = Release; }; - A0A1595A7BBE7F8799549FBA6D016C5F /* Release */ = { + AD75EFC2881A641F822B2A1E19BFCC77 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 62982164F2B5DEF7B82A870F71FBFE74 /* Observable.xcconfig */; + baseConfigurationReference = F0F91F53502405804E4AFA6E2F5FF2A8 /* Pods-GradientLoadingBar_Example.debug.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-GradientLoadingBar_Example/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_GradientLoadingBar_Example; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + BC2EE1F2621DE364AB5C3BD0FB59458E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9AC0D5BE1D3E0BD55B9098C545D90E0E /* Observable.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -773,7 +818,7 @@ }; name = Release; }; - B57951D085A1B98A97F8A1062A5E5C5B /* Debug */ = { + CE271817CBC0BF8DB9C70409CD854479 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -783,6 +828,7 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -820,13 +866,13 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_INHIBIT_ALL_WARNINGS = NO; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; @@ -836,9 +882,72 @@ }; name = Debug; }; - DA21818ADCCFDBE3DC9DF3903419EB9E /* Release */ = { + CEAF18613F6A1C4D7E7343AC88EA547C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 53267FC01B3E758EC7BC06C1D2220B74 /* Pods-GradientLoadingBar_Tests.release.xcconfig */; + baseConfigurationReference = A7EE3290A69260383C55CBE340D72011 /* Pods-GradientLoadingBar_Tests.debug.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-GradientLoadingBar_Tests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-GradientLoadingBar_Tests/Pods-GradientLoadingBar_Tests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_GradientLoadingBar_Tests; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + D16C677267F7CF3DA3C42091B0971878 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 22AA11253C3E2F00F94AAA627F044BD9 /* GradientLoadingBar.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/GradientLoadingBar/GradientLoadingBar-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/GradientLoadingBar/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/GradientLoadingBar/GradientLoadingBar.modulemap"; + PRODUCT_NAME = GradientLoadingBar; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + F2A7EE53A43335C89262633065606AE3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D9DE45D95CCA0E5D76226B173898C17B /* Pods-GradientLoadingBar_Tests.release.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -869,115 +978,50 @@ }; name = Release; }; - DECE6BFB43A907A4C92FE148A3F86861 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 62982164F2B5DEF7B82A870F71FBFE74 /* Observable.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/Observable/Observable-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Observable/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/Observable/Observable.modulemap"; - PRODUCT_NAME = Observable; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - F6449C0ACB4664CBCE4ABF2F2A8059F1 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 501B9AB1C1F1E59F4628E81A7970CD37 /* Pods-GradientLoadingBar_Example.release.xcconfig */; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-GradientLoadingBar_Example/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_GradientLoadingBar_Example; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 00E38063FE1C1ED092C80D09810F4D14 /* Build configuration list for PBXNativeTarget "Observable" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DECE6BFB43A907A4C92FE148A3F86861 /* Debug */, - A0A1595A7BBE7F8799549FBA6D016C5F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - B57951D085A1B98A97F8A1062A5E5C5B /* Debug */, - 6F9224530522DD3C735EC96CF142642E /* Release */, + CE271817CBC0BF8DB9C70409CD854479 /* Debug */, + 798F283DEF5D6E82C13E1DBA995AA1B8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 37515D7500C740E1F892D462242EE790 /* Build configuration list for PBXNativeTarget "GradientLoadingBar" */ = { + 994EE5A58AF8B36DD55E52C1787AD1DD /* Build configuration list for PBXNativeTarget "Observable" */ = { isa = XCConfigurationList; buildConfigurations = ( - 5C79A6E75624EAA3969DA7A663BBA669 /* Debug */, - 7BC683054BF52690B352E993FC6649C1 /* Release */, + 23B2E1163053F92E823AD3DAAE8AB4AF /* Debug */, + BC2EE1F2621DE364AB5C3BD0FB59458E /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 769F26B1F11CC0AB6BE2AE773FF66E01 /* Build configuration list for PBXNativeTarget "Pods-GradientLoadingBar_Tests" */ = { + B3073FF85CC042B5C8BF8C85D5503C1E /* Build configuration list for PBXNativeTarget "Pods-GradientLoadingBar_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2391AB0DF476D0BF15DA502FD5D56E68 /* Debug */, - DA21818ADCCFDBE3DC9DF3903419EB9E /* Release */, + AD75EFC2881A641F822B2A1E19BFCC77 /* Debug */, + 7A4149B63F94A67C1FFDB91CA24D7781 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - CE51B32DA3B3093FF3BA59642B6C54A8 /* Build configuration list for PBXNativeTarget "Pods-GradientLoadingBar_Example" */ = { + D104056D84CD79BDB5002659695AC7FB /* Build configuration list for PBXNativeTarget "GradientLoadingBar" */ = { isa = XCConfigurationList; buildConfigurations = ( - 1154D18835E11DCF4C6D3ABBD94FC8B2 /* Debug */, - F6449C0ACB4664CBCE4ABF2F2A8059F1 /* Release */, + D16C677267F7CF3DA3C42091B0971878 /* Debug */, + A8BA56DA06DF9659C35399F99D7564CC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FC7BD56761426B5F94E35E60E95CBA50 /* Build configuration list for PBXNativeTarget "Pods-GradientLoadingBar_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CEAF18613F6A1C4D7E7343AC88EA547C /* Debug */, + F2A7EE53A43335C89262633065606AE3 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/GradientLoadingBar.xcscheme b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/GradientLoadingBar.xcscheme index 36db50b..891390a 100644 --- a/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/GradientLoadingBar.xcscheme +++ b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/GradientLoadingBar.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -45,7 +45,7 @@ diff --git a/Example/Pods/Target Support Files/GradientLoadingBar/GradientLoadingBar.xcconfig b/Example/Pods/Target Support Files/GradientLoadingBar/GradientLoadingBar.xcconfig index 934bcd4..114eee8 100644 --- a/Example/Pods/Target Support Files/GradientLoadingBar/GradientLoadingBar.xcconfig +++ b/Example/Pods/Target Support Files/GradientLoadingBar/GradientLoadingBar.xcconfig @@ -2,7 +2,7 @@ CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/GradientLoadingBar FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Observable" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SwiftFormat" "${PODS_ROOT}/Headers/Public/SwiftLint" -OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" "-suppress-warnings" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} diff --git a/Example/Pods/Target Support Files/Observable/Observable.xcconfig b/Example/Pods/Target Support Files/Observable/Observable.xcconfig index 243ff81..a369bc9 100644 --- a/Example/Pods/Target Support Files/Observable/Observable.xcconfig +++ b/Example/Pods/Target Support Files/Observable/Observable.xcconfig @@ -1,7 +1,7 @@ CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Observable GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SwiftFormat" "${PODS_ROOT}/Headers/Public/SwiftLint" -OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" "-suppress-warnings" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} diff --git a/Example/Pods/Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example-acknowledgements.markdown index c855ef2..cee7fec 100644 --- a/Example/Pods/Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example-acknowledgements.markdown +++ b/Example/Pods/Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example-acknowledgements.markdown @@ -49,54 +49,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -## SwiftFormat - -MIT License - -Copyright (c) 2016 Nick Lockwood - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -## SwiftLint - -The MIT License (MIT) - -Copyright (c) 2015 Realm Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - Generated by CocoaPods - https://cocoapods.org diff --git a/Example/Pods/Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example-acknowledgements.plist index 610c2bd..316a391 100644 --- a/Example/Pods/Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example-acknowledgements.plist +++ b/Example/Pods/Target Support Files/Pods-GradientLoadingBar_Example/Pods-GradientLoadingBar_Example-acknowledgements.plist @@ -73,68 +73,6 @@ THE SOFTWARE. Type PSGroupSpecifier - - FooterText - MIT License - -Copyright (c) 2016 Nick Lockwood - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - License - MIT - Title - SwiftFormat - Type - PSGroupSpecifier - - - FooterText - The MIT License (MIT) - -Copyright (c) 2015 Realm Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - License - MIT - Title - SwiftLint - Type - PSGroupSpecifier - FooterText Generated by CocoaPods - https://cocoapods.org diff --git a/Example/Tests/Helpers/Extensions/Observable+ObserveDistinctTestCase.swift b/Example/Tests/Helpers/Extensions/Observable+ObserveDistinctTestCase.swift new file mode 100644 index 0000000..07b5593 --- /dev/null +++ b/Example/Tests/Helpers/Extensions/Observable+ObserveDistinctTestCase.swift @@ -0,0 +1,54 @@ +// +// Observable+ObserveDistinctTestCase.swift +// GradientLoadingBarTests +// +// Created by Felix Mau on 25.08.18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import XCTest +import Observable + +class ObservableObserveDistinctTestCase: XCTestCase { + func testObserveDistinctShouldNotifyListener() { + // Given + let prevValue = 123 + let nextValue = 456 + + let observable = Observable(prevValue) + + var observeCallCounter = 0 + + var disposeBag = Disposal() + observable.observeDistinct { _, _ in + observeCallCounter += 1 + }.add(to: &disposeBag) + + // When + observable.value = nextValue + + // Then + XCTAssertEqual(observeCallCounter, 2) + } + + func testObserveDistinctShouldNotNotifyListenerDueToSameValue() { + // Given + let prevValue = 123 + let nextValue = 123 + + let observable = Observable(prevValue) + + var observeCallCounter = 0 + + var disposeBag = Disposal() + observable.observeDistinct { _, _ in + observeCallCounter += 1 + }.add(to: &disposeBag) + + // When + observable.value = nextValue + + // Then + XCTAssertEqual(observeCallCounter, 1) + } +} diff --git a/Example/Tests/ViewModel/GradientLoadingBarViewModelTestCase.swift b/Example/Tests/ViewModel/GradientLoadingBarViewModelTestCase.swift index c73df84..f21a4b2 100644 --- a/Example/Tests/ViewModel/GradientLoadingBarViewModelTestCase.swift +++ b/Example/Tests/ViewModel/GradientLoadingBarViewModelTestCase.swift @@ -15,6 +15,7 @@ import XCTest class GradientLoadingBarViewModelTestCase: XCTestCase { private var superview: UIView! + private var durations: Durations! private var sharedApplicationMock: SharedApplicationMock! private var notificationCenter: NotificationCenter! @@ -24,10 +25,15 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { super.setUp() superview = UIView() + durations = Durations(fadeIn: 1.2, + fadeOut: 3.4, + progress: 5.6) + sharedApplicationMock = SharedApplicationMock() notificationCenter = NotificationCenter() viewModel = GradientLoadingBarViewModel(superview: superview, + durations: durations, sharedApplication: sharedApplicationMock, notificationCenter: notificationCenter) } @@ -36,6 +42,7 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { viewModel = nil superview = nil + durations = nil notificationCenter = nil sharedApplicationMock = nil @@ -56,6 +63,7 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { func testListenerForSuperviewShouldBeInformedAfterUIWindowDidBecomeKeyNotification() { // Given let viewModel = GradientLoadingBarViewModel(superview: nil, + durations: durations, sharedApplication: sharedApplicationMock, notificationCenter: notificationCenter) @@ -74,13 +82,14 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { }.add(to: &disposal) // When - notificationCenter.post(name: UIWindow.didBecomeKeyNotification, + notificationCenter.post(name: .UIWindowDidBecomeKey, object: nil) } func testListenerForSuperviewShouldBeInformedAfterUIWindowDidBecomeKeyNotificationJustOnce() { // Given let viewModel = GradientLoadingBarViewModel(superview: nil, + durations: durations, sharedApplication: sharedApplicationMock, notificationCenter: notificationCenter) @@ -101,7 +110,7 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { // When for _ in 1 ... 3 { - notificationCenter.post(name: UIWindow.didBecomeKeyNotification, + notificationCenter.post(name: .UIWindowDidBecomeKey, object: nil) } @@ -115,7 +124,7 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { viewModel.show() // Then - XCTAssertTrue(viewModel.isVisible.value) + XCTAssertTrue(viewModel.isVisible.value.isHidden) } func testShowShouldUpdateVisibilityJustOnce() { @@ -133,7 +142,7 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { } // Then - XCTAssertTrue(viewModel.isVisible.value) + XCTAssertTrue(viewModel.isVisible.value.isHidden) XCTAssertEqual(visiblityCounter, 2, "After the initial call to the observer, we expect it to be notified just one more time.") } @@ -145,7 +154,7 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { // When viewModel.hide() - XCTAssertFalse(viewModel.isVisible.value) + XCTAssertFalse(viewModel.isVisible.value.isHidden) } func testHideShouldUpdateVisibilityJustOnce() { @@ -166,7 +175,7 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { } // Then - XCTAssertFalse(viewModel.isVisible.value) + XCTAssertFalse(viewModel.isVisible.value.isHidden) XCTAssertEqual(visiblityCounter, 2, "After the initial call to the observer, we expect it to be notified just one more time.") } @@ -175,7 +184,7 @@ class GradientLoadingBarViewModelTestCase: XCTestCase { viewModel.toggle() let isOdd = idx % 2 == 1 - XCTAssertEqual(viewModel.isVisible.value, isOdd) + XCTAssertEqual(viewModel.isVisible.value.isHidden, isOdd) } } } diff --git a/Extensions/Observable+ObserveDistinct.swift b/Extensions/Observable+ObserveDistinct.swift new file mode 100644 index 0000000..360cc09 --- /dev/null +++ b/Extensions/Observable+ObserveDistinct.swift @@ -0,0 +1,21 @@ +// +// Observable+ObserveDistinct.swift +// GradientLoadingBar +// +// Created by Felix Mau on 25.08.18. +// + +import Foundation +import Observable + +extension Observable where T: Equatable { + /// A wrapper around the `observe` method, that checks whether the previous value is different from the next value. + /// If they are equal the listener will not be notified. This is useful to prevent unnecessary UI updates. + public func observeDistinct(_ observer: @escaping Observer) -> Disposable { + return observe({ nextValue, prevValue in + guard nextValue != prevValue else { return } + + observer(nextValue, prevValue) + }) + } +} diff --git a/Extensions/UIColor/UIColor+DefaultGradientColors.swift b/Extensions/UIColor/UIColor+DefaultGradientColors.swift new file mode 100644 index 0000000..2ba09fc --- /dev/null +++ b/Extensions/UIColor/UIColor+DefaultGradientColors.swift @@ -0,0 +1,21 @@ +// +// UIColor+DefaultGradientColors.swift +// GradientLoadingBar +// +// Created by Felix Mau on 26.08.18. +// + +import UIKit + +extension UIColor { + // iOS color palette + // From: https://codepen.io/marcobiedermann/pen/LExXWW + public static let defaultGradientColorList = [ + UIColor(hex: "#4cd964"), + UIColor(hex: "#5ac8fa"), + UIColor(hex: "#007aff"), + UIColor(hex: "#34aadc"), + UIColor(hex: "#5856d6"), + UIColor(hex: "#ff2d55") + ] +} diff --git a/GradientLoadingBar/Classes/Helpers/Extensions/UIColor+Initializers.swift b/Extensions/UIColor/UIColor+Initializers.swift similarity index 100% rename from GradientLoadingBar/Classes/Helpers/Extensions/UIColor+Initializers.swift rename to Extensions/UIColor/UIColor+Initializers.swift diff --git a/GradientLoadingBar/Classes/GradientLoadingBarController.swift b/GradientLoadingBar/Classes/GradientLoadingBarController.swift index 9b86d07..0d2f45e 100644 --- a/GradientLoadingBar/Classes/GradientLoadingBarController.swift +++ b/GradientLoadingBar/Classes/GradientLoadingBarController.swift @@ -13,41 +13,15 @@ import UIKit public typealias GradientLoadingBar = GradientLoadingBarController open class GradientLoadingBarController { - // MARK: - Types - - /// Struct used for default parameters in initialization - public struct DefaultValues { - /// Height of gradient bar. - public static let height = 2.5 - - /// Configuration with durations for each animation. - public static let durations = Durations(fadeIn: 0.33, fadeOut: 0.66, progress: 3.33) - - // iOS color palette - // From: https://codepen.io/marcobiedermann/pen/LExXWW - public static let gradientColors = [ - UIColor(hex: "#4cd964"), - UIColor(hex: "#5ac8fa"), - UIColor(hex: "#007aff"), - UIColor(hex: "#34aadc"), - UIColor(hex: "#5856d6"), - UIColor(hex: "#ff2d55") - ] - } - // MARK: - Public properties - /// Boolean flag, true if gradient view is currently visible, otherwise false. - public var isVisible: Bool { - return viewModel.isVisible.value - } + /// The height of the gradient bar. + /// Notice: Has to be public to allow overwriting `setupConstraints()` + public let height: Double /// View containing the gradient layer. public let gradientView: GradientView - /// Height of gradient bar. - public let height: Double - /// Singleton instance. public static var shared = GradientLoadingBar() @@ -64,23 +38,26 @@ open class GradientLoadingBarController { /// Creates a new gradient loading bar instance. /// /// Parameters: - /// - height: Height of the gradient bar - /// - durations: Configuration with durations for each animation - /// - gradientColorList: Colors used for the gradient - /// - superview: View containing the gradient bar + /// - height: Height of the gradient bar + /// - durations: Configuration with durations for each animation + /// - gradientColorList: Colors used for the gradient + /// - shouldHandleSafeAreaInsets: Flag whether the top layout constraint should respect `safeAreaLayoutGuide` + /// - superview: View containing the gradient bar /// /// Returns: Instance with gradient bar - public init(height: Double = DefaultValues.height, - durations: Durations = DefaultValues.durations, - gradientColorList: [UIColor] = DefaultValues.gradientColors, + public init(height: Double = 2.5, + durations: Durations = .default, + gradientColorList: [UIColor] = UIColor.defaultGradientColorList, onView superview: UIView? = nil) { self.height = height - gradientView = GradientView(animationDurations: durations, + gradientView = GradientView(progressAnimationDuration: durations.progress, gradientColorList: gradientColorList) + gradientView.isHidden = true + gradientView.clipsToBounds = true - viewModel = GradientLoadingBarViewModel(superview: superview) - + viewModel = GradientLoadingBarViewModel(superview: superview, + durations: durations) bindViewModelToView() } @@ -93,30 +70,41 @@ open class GradientLoadingBarController { // MARK: - Private methods private func bindViewModelToView() { - viewModel.isVisible.observe { [weak self] nextValue, _ in - if nextValue { - self?.gradientView.show() - } else { - self?.gradientView.hide() - } + viewModel.isVisible.observeDistinct { [weak self] nextValue, _ in + self?.updateGradientViewVisibility(nextValue) }.add(to: &disposal) - viewModel.superview.observe { [weak self] nextValue, _ in - guard self?.gradientView.superview == nil else { - // The viewmodel informed us eventhough we already have a valid superview. This isn't supposed to happen, therefore we safely exit here. - return - } - - guard let superview = nextValue else { - // We've got an invalid superview, therefore we safely exit here. - return - } - - self?.addGradientView(to: superview) + viewModel.superview.observeDistinct { [weak self] nextValue, _ in + self?.addGradientView(to: nextValue) }.add(to: &disposal) } - private func addGradientView(to superview: UIView) { + private func updateGradientViewVisibility(_ animatedVisibilityUpdate: GradientLoadingBarViewModel.AnimatedVisibilityUpdate) { + let isHidden = animatedVisibilityUpdate.isHidden + if !isHidden { + gradientView.isHidden = false + } + + UIView.animate(withDuration: animatedVisibilityUpdate.duration, animations: { + self.gradientView.alpha = animatedVisibilityUpdate.alpha + }, completion: { isFinished in + if isFinished && isHidden { + self.gradientView.isHidden = true + } + }) + } + + private func addGradientView(to superview: UIView?) { + guard gradientView.superview == nil else { + // The viewmodel informed us eventhough we already have a valid superview. + return + } + + guard let superview = superview else { + // We've received an invalid superview. + return + } + gradientView.translatesAutoresizingMaskIntoConstraints = false superview.addSubview(gradientView) @@ -127,16 +115,8 @@ open class GradientLoadingBarController { /// Apply layout contraints for gradient loading view. open func setupConstraints(superview: UIView) { - let superViewTopAnchor: NSLayoutYAxisAnchor - if #available(iOS 11.0, *) { - // Handle iPhone X Layout, so gradient view is underneath the status bar - superViewTopAnchor = superview.safeAreaLayoutGuide.topAnchor - } else { - superViewTopAnchor = superview.topAnchor - } - NSLayoutConstraint.activate([ - gradientView.topAnchor.constraint(equalTo: superViewTopAnchor), + gradientView.topAnchor.constraint(equalTo: superview.topAnchor), gradientView.heightAnchor.constraint(equalToConstant: CGFloat(height)), gradientView.leadingAnchor.constraint(equalTo: superview.leadingAnchor), @@ -160,6 +140,49 @@ open class GradientLoadingBarController { } } +// MARK: - Safe Area Gradient Loading Bar + +/// +open class SafeAreaGradientLoadingBar: GradientLoadingBar { + // MARK: - Public properties + + // override public static var shared = SafeAreaGradientLoadingBar() as GradientLoadingBar + + // MARK: - Public methods + + open override func setupConstraints(superview: UIView) { + let superViewTopAnchor: NSLayoutYAxisAnchor + if #available(iOS 11.0, *) { + superViewTopAnchor = superview.safeAreaLayoutGuide.topAnchor + } else { + superViewTopAnchor = superview.topAnchor + } + + NSLayoutConstraint.activate([ + gradientView.leadingAnchor.constraint(equalTo: superview.leadingAnchor), + gradientView.trailingAnchor.constraint(equalTo: superview.trailingAnchor), + + gradientView.topAnchor.constraint(equalTo: superViewTopAnchor), + gradientView.heightAnchor.constraint(equalToConstant: CGFloat(height)) + ]) + } +} + +// MARK: - Bottom Gradient Loading Bar + +/// +open class BottomGradientLoadingBar: GradientLoadingBar { + open override func setupConstraints(superview: UIView) { + NSLayoutConstraint.activate([ + gradientView.leadingAnchor.constraint(equalTo: superview.leadingAnchor), + gradientView.trailingAnchor.constraint(equalTo: superview.trailingAnchor), + + gradientView.bottomAnchor.constraint(equalTo: superview.bottomAnchor), + gradientView.heightAnchor.constraint(equalToConstant: CGFloat(height)) + ]) + } +} + // MARK: - Deprecated methods extension GradientLoadingBarController { @@ -177,8 +200,8 @@ extension GradientLoadingBarController { /// /// Returns: Instance with gradient bar @available(*, deprecated, message: "Please use `init(height: Double, durations: Durations, gradientColorList: [UIColor], onView: UIView?)` instead") - public convenience init(height: Double = DefaultValues.height, - durations: Durations = DefaultValues.durations, + public convenience init(height: Double = 2.5, + durations: Durations = .default, gradientColors: [CGColor], onView superview: UIView? = nil) { self.init(height: height, diff --git a/GradientLoadingBar/Classes/ViewModel/GradientLoadingBarViewModel.swift b/GradientLoadingBar/Classes/ViewModel/GradientLoadingBarViewModel.swift index f6bf8a3..c3474b4 100644 --- a/GradientLoadingBar/Classes/ViewModel/GradientLoadingBarViewModel.swift +++ b/GradientLoadingBar/Classes/ViewModel/GradientLoadingBarViewModel.swift @@ -10,16 +10,36 @@ import Observable /// The `GradientLoadingBarViewModel` class is responsible for the visibility state of the gradient view. class GradientLoadingBarViewModel { + // MARK: - Types + + /// + struct AnimatedVisibilityUpdate: Equatable { + /// + static let zero = AnimatedVisibilityUpdate(duration: 0.0, alpha: 0.0, isHidden: true) + + /// The duration for the visibility update. + let duration: TimeInterval + + /// New alpha value. + let alpha: CGFloat + + /// Boolean flag, whether the view should be hidden after the animation is finished. + let isHidden: Bool + } + // MARK: - Public properties /// Boolean flag determinating whether gradient view is currently visible. - private(set) var isVisible = Observable(false) + let isVisible: Observable = Observable(.zero) /// Boolean flag determinating whether gradient view is currently visible. - private(set) var superview: Observable = Observable(nil) + let superview: Observable = Observable(nil) // MARK: - Private properties + /// Configuration with durations for each animation. + private let durations: Durations + // MARK: - Dependencies private let sharedApplication: UIApplicationProtocol @@ -27,7 +47,11 @@ class GradientLoadingBarViewModel { // MARK: - Constructor - init(superview: UIView?, sharedApplication: UIApplicationProtocol = UIApplication.shared, notificationCenter: NotificationCenter = .default) { + init(superview: UIView?, + durations: Durations, + sharedApplication: UIApplicationProtocol = UIApplication.shared, + notificationCenter: NotificationCenter = .default) { + self.durations = durations self.sharedApplication = sharedApplication self.notificationCenter = notificationCenter @@ -38,7 +62,7 @@ class GradientLoadingBarViewModel { // Therefore we setup an observer to inform the listeners when it's ready. notificationCenter.addObserver(self, selector: #selector(didReceiveUiWindowDidBecomeKeyNotification(_:)), - name: UIWindow.didBecomeKeyNotification, + name: .UIWindowDidBecomeKey, object: nil) } } @@ -51,6 +75,7 @@ class GradientLoadingBarViewModel { // Prevent informing the listeners multiple times. notificationCenter.removeObserver(self) + // superview.value = keyWindow } @@ -58,21 +83,25 @@ class GradientLoadingBarViewModel { /// Fades in the gradient loading bar. func show() { - guard !isVisible.value else { return } - - isVisible.value = true + isVisible.value = AnimatedVisibilityUpdate(duration: durations.fadeIn, + alpha: 1.0, + isHidden: false) } /// Fades out the gradient loading bar. func hide() { - guard isVisible.value else { return } - - isVisible.value = false + isVisible.value = AnimatedVisibilityUpdate(duration: durations.fadeOut, + alpha: 0.0, + isHidden: true) } /// Toggle visiblity of gradient loading bar. func toggle() { - isVisible.value.toggle() + if isVisible.value.isHidden { + show() + } else { + hide() + } } } diff --git a/GradientLoadingBar/Classes/Views/GradientView.swift b/GradientLoadingBar/Classes/Views/GradientView.swift index d830d0a..627c581 100644 --- a/GradientLoadingBar/Classes/Views/GradientView.swift +++ b/GradientLoadingBar/Classes/Views/GradientView.swift @@ -13,10 +13,20 @@ public final class GradientView: UIView { // MARK: - Types /// Animation-Keys for each animation - enum AnimationKeys: String { - case fadeIn - case fadeOut - case progress + static let progressAnimationKey = "GradientView--progressAnimation" + + // MARK: - Public properties + + public override var isHidden: Bool { + didSet { + super.isHidden = isHidden + + if isHidden { + stopProgressAnimation() + } else { + startProgressAnimation() + } + } } // MARK: - Private properties @@ -24,8 +34,8 @@ public final class GradientView: UIView { /// Layer holding the gradient. private let gradientLayer = CAGradientLayer() - /// Configuration with durations for each animation. - private let animationDurations: Durations + /// Duration for the progress animation. + private let progressAnimationDuration: TimeInterval /// Colors used for the gradient. private let gradientColorList: [UIColor] @@ -35,12 +45,12 @@ public final class GradientView: UIView { /// Initializes a new gradient view (holding the `CALayer` used for the gradient) /// /// Parameters: - /// - animationDurations: Configuration with durations for each animation - /// - gradientColors: Colors used for the gradient + /// - progressAnimationDuration: Duration for the progress animation. + /// - gradientColorList: Colors used for the gradient. /// /// Returns: Instance with gradient view - init(animationDurations: Durations, gradientColorList: [UIColor]) { - self.animationDurations = animationDurations + init(progressAnimationDuration: TimeInterval, gradientColorList: [UIColor]) { + self.progressAnimationDuration = progressAnimationDuration self.gradientColorList = gradientColorList super.init(frame: .zero) @@ -52,11 +62,27 @@ public final class GradientView: UIView { fatalError("init(coder:) has not been implemented") } - // MARK: - Layout + public override func layoutSubviews() { + super.layoutSubviews() + + // Unfortunately CGLayer is not affected by autolayout, so any change in the size of the view will not change the gradient layer. + // That's why we'll have to update the frame here manually. + // Three times of the width in order to apply normal, reversed and normal gradient to simulate infinte animation + gradientLayer.frame = CGRect(x: 0, y: 0, width: 3 * bounds.size.width, height: bounds.size.height) + + gradientLayer.anchorPoint = CGPoint(x: 0, y: 0) + gradientLayer.position = CGPoint(x: 0, y: 0) + } + + public override func point(inside _: CGPoint, with _: UIEvent?) -> Bool { + // Passing all touches to the next view (if any), in the view stack. + // + return false + } + + // MARK: - Private methods private func setupGradientLayer() { - gradientLayer.opacity = 0.0 - gradientLayer.startPoint = .zero gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0) @@ -72,87 +98,22 @@ public final class GradientView: UIView { layer.insertSublayer(gradientLayer, at: 0) } - public override func layoutSubviews() { - super.layoutSubviews() - - // Unfortunately CGLayer is not affected by autolayout, so any change in the size of the view will not change the gradient layer. - // That's why we'll have to update the frame here manually. - - // Three times of the width in order to apply normal, reversed and normal gradient to simulate infinte animation - gradientLayer.frame = CGRect(x: 0, y: 0, width: 3 * bounds.size.width, height: bounds.size.height) - - gradientLayer.anchorPoint = CGPoint(x: 0, y: 0) - gradientLayer.position = CGPoint(x: 0, y: 0) - } - - // MARK: - Show / Hide - - /// Helper to toggle gradient layer visibility. - private func updateGradientLayerVisibility(fromOpacity: CGFloat, toOpacity: CGFloat, duration: TimeInterval, animationKey: String) { - let animation = CABasicAnimation(keyPath: "opacity") - animation.delegate = self - - animation.fromValue = fromOpacity - animation.toValue = toOpacity - - animation.duration = duration - - animation.fillMode = .forwards - animation.isRemovedOnCompletion = false - - gradientLayer.add(animation, forKey: animationKey) - } - - /// Fades in gradient view - public func show() { - // Remove possible existing fade-out animation - gradientLayer.removeAnimation(forKey: AnimationKeys.fadeOut.rawValue) - - updateGradientLayerVisibility(fromOpacity: 0.0, - toOpacity: 1.0, - duration: animationDurations.fadeIn, - animationKey: AnimationKeys.fadeIn.rawValue) - } - - /// Fades out gradient view - public func hide() { - // Remove possible existing fade-in animation - gradientLayer.removeAnimation(forKey: AnimationKeys.fadeIn.rawValue) - - updateGradientLayerVisibility(fromOpacity: 1.0, - toOpacity: 0.0, - duration: animationDurations.fadeOut, - animationKey: AnimationKeys.fadeOut.rawValue) - } -} - -// MARK: - CAAnimationDelegate - -extension GradientView: CAAnimationDelegate { - public func animationDidStart(_ anim: CAAnimation) { - guard anim == gradientLayer.animation(forKey: AnimationKeys.fadeIn.rawValue) else { - // We're only interested in the "fadeIn" animation, so exit here. - return - } - - // Start progress animation together with start of fade-in animation + /// + private func startProgressAnimation() { + // Start progress animation together with start of fade-in animation. let animation = CABasicAnimation(keyPath: "position") animation.fromValue = CGPoint(x: -2 * bounds.size.width, y: 0) animation.toValue = CGPoint.zero - animation.duration = animationDurations.progress + animation.duration = progressAnimationDuration animation.repeatCount = Float.infinity - gradientLayer.add(animation, forKey: AnimationKeys.progress.rawValue) + gradientLayer.add(animation, forKey: GradientView.progressAnimationKey) } - public func animationDidStop(_ anim: CAAnimation, finished _: Bool) { - guard anim == gradientLayer.animation(forKey: AnimationKeys.fadeOut.rawValue) else { - // We're only interested in the "fadeOut" animation, so exit here. - return - } - - // Stop progress animation together with finished fade-out animation - gradientLayer.removeAnimation(forKey: AnimationKeys.progress.rawValue) + /// + private func stopProgressAnimation() { + // Stop progress animation together with finished fade-out animation. + gradientLayer.removeAnimation(forKey: GradientView.progressAnimationKey) } } diff --git a/GradientLoadingBar/Classes/Helpers/Structs/Durations.swift b/Structs/Durations.swift similarity index 88% rename from GradientLoadingBar/Classes/Helpers/Structs/Durations.swift rename to Structs/Durations.swift index 6f12e79..b809546 100644 --- a/GradientLoadingBar/Classes/Helpers/Structs/Durations.swift +++ b/Structs/Durations.swift @@ -11,7 +11,12 @@ import Foundation /// Animation durations for fade-in / fade-out and progress animations. /// All values are in seconds. public struct Durations { - // MARK: - Properties + // MARK: - Config + + /// + public static let `default` = Durations(fadeIn: 0.33, fadeOut: 0.66, progress: 3.33) + + // MARK: - Public Properties /// Duration (in sec.) for fade in animation let fadeIn: Double