From 0952b252d8f5cf7d2efd665fd4e7fe48f63139ff Mon Sep 17 00:00:00 2001 From: Felix Mau Date: Mon, 25 Sep 2017 08:47:49 +0200 Subject: [PATCH] * Fix never adding gradient view to "keyWindow" if it is not available on first call to "show()" --- CHANGELOG.md | 11 ++++-- GradientLoadingBar.podspec | 4 +- GradientLoadingBar.xcodeproj/project.pbxproj | 30 +++++++++++++-- GradientLoadingBar/GradientLoadingBar.swift | 27 +++++++------ .../NotificationCenter+ObserveOnce.swift | 38 +++++++++++++++++++ .../{ => UIColor}/UIColor+Initializers.swift | 0 GradientLoadingBar/Views/GradientView.swift | 3 ++ readme.md | 2 +- 8 files changed, 91 insertions(+), 24 deletions(-) create mode 100644 GradientLoadingBar/Helpers/Extensions/NotificationCenter/NotificationCenter+ObserveOnce.swift rename GradientLoadingBar/Helpers/Extensions/{ => UIColor}/UIColor+Initializers.swift (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52d3a43..e06ec9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [Unreleased] +## [1.1.3] - 2017-25-09 +### Fixed + - Fix never adding gradient view to "keyWindow" if it is not available on first call to "show()" + ## [1.1.2] - 2017-27-08 ### Added - Basic tests / TravisCI integration @@ -23,13 +27,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a ## [1.1.0] - 2017-28-02 ### Changed - - allow changing gradient colors + - Allow changing gradient colors ## [1.0.0] - 2016-28-12 -- initial release +- Initial release -[Unreleased]: https://github.com/fxm90/GradientLoadingBar/compare/1.1.2...master +[Unreleased]: https://github.com/fxm90/GradientLoadingBar/compare/1.1.3...master +[1.1.3]: https://github.com/fxm90/GradientLoadingBar/compare/1.1.2...1.1.3 [1.1.2]: https://github.com/fxm90/GradientLoadingBar/compare/1.1.1...1.1.2 [1.1.1]: https://github.com/fxm90/GradientLoadingBar/compare/1.1.0...1.1.1 [1.1.0]: https://github.com/fxm90/GradientLoadingBar/compare/1.0.0...1.1.0 diff --git a/GradientLoadingBar.podspec b/GradientLoadingBar.podspec index 3db5f2c..1b8eef3 100644 --- a/GradientLoadingBar.podspec +++ b/GradientLoadingBar.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'GradientLoadingBar' - s.version = '1.1.2' + s.version = '1.1.3' s.license = { :type => 'MIT', :file => 'LICENSE' } s.summary = 'An animated gradient loading bar.' s.description = 'An animated gradient loading bar. Inspired by http://www.cssscript.com/ios-style-gradient-progress-bar-with-pure-css-css3/' @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.screenshot = 'http://felix.hamburg/files/github/gradient-loading-bar/screen.gif' s.author = { 'Felix Mau' => 'contact@felix.hamburg' } - s.source = { :git => 'https://github.com/fxm90/GradientLoadingBar.git', :tag => '1.1.2' } + s.source = { :git => 'https://github.com/fxm90/GradientLoadingBar.git', :tag => '1.1.3' } s.source_files = 'GradientLoadingBar', 'GradientLoadingBar/**/*.swift' s.platform = :ios, '9.0' diff --git a/GradientLoadingBar.xcodeproj/project.pbxproj b/GradientLoadingBar.xcodeproj/project.pbxproj index 47a93a4..fff8cc0 100644 --- a/GradientLoadingBar.xcodeproj/project.pbxproj +++ b/GradientLoadingBar.xcodeproj/project.pbxproj @@ -11,9 +11,10 @@ 97AE29101E13C5B400C454C6 /* GradientLoadingBar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97AE29061E13C5B400C454C6 /* GradientLoadingBar.framework */; }; 97AE29171E13C5B400C454C6 /* GradientLoadingBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 97AE29091E13C5B400C454C6 /* GradientLoadingBar.h */; settings = {ATTRIBUTES = (Public, ); }; }; 97AE29281E13C5E500C454C6 /* GradientLoadingBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97AE29201E13C5E500C454C6 /* GradientLoadingBar.swift */; }; - 97AE29291E13C5E500C454C6 /* UIColor+Initializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97AE29231E13C5E500C454C6 /* UIColor+Initializers.swift */; }; 97AE292A1E13C5E500C454C6 /* Durations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97AE29251E13C5E500C454C6 /* Durations.swift */; }; 97AE292B1E13C5E500C454C6 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97AE29271E13C5E500C454C6 /* GradientView.swift */; }; + 97CC3E7F1F77838700116D41 /* NotificationCenter+ObserveOnce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CC3E7E1F77838700116D41 /* NotificationCenter+ObserveOnce.swift */; }; + 97CC3E801F77898E00116D41 /* UIColor+Initializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CC3E7C1F77834400116D41 /* UIColor+Initializers.swift */; }; 97CDC6D61F51E932006249FE /* UIColor+InitializersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97CDC6D51F51E932006249FE /* UIColor+InitializersTests.swift */; }; /* End PBXBuildFile section */ @@ -35,9 +36,10 @@ 97AE290F1E13C5B400C454C6 /* GradientLoadingBarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GradientLoadingBarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 97AE29161E13C5B400C454C6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 97AE29201E13C5E500C454C6 /* GradientLoadingBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientLoadingBar.swift; sourceTree = ""; }; - 97AE29231E13C5E500C454C6 /* UIColor+Initializers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Initializers.swift"; sourceTree = ""; }; 97AE29251E13C5E500C454C6 /* Durations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Durations.swift; sourceTree = ""; }; 97AE29271E13C5E500C454C6 /* GradientView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = ""; }; + 97CC3E7C1F77834400116D41 /* UIColor+Initializers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Initializers.swift"; sourceTree = ""; }; + 97CC3E7E1F77838700116D41 /* NotificationCenter+ObserveOnce.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationCenter+ObserveOnce.swift"; sourceTree = ""; }; 97CDC6D51F51E932006249FE /* UIColor+InitializersTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+InitializersTests.swift"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -120,7 +122,8 @@ 97AE29221E13C5E500C454C6 /* Extensions */ = { isa = PBXGroup; children = ( - 97AE29231E13C5E500C454C6 /* UIColor+Initializers.swift */, + 97CC3E7D1F77836200116D41 /* NotificationCenter */, + 97CC3E7B1F77834400116D41 /* UIColor */, ); path = Extensions; sourceTree = ""; @@ -141,6 +144,22 @@ path = Views; sourceTree = ""; }; + 97CC3E7B1F77834400116D41 /* UIColor */ = { + isa = PBXGroup; + children = ( + 97CC3E7C1F77834400116D41 /* UIColor+Initializers.swift */, + ); + path = UIColor; + sourceTree = ""; + }; + 97CC3E7D1F77836200116D41 /* NotificationCenter */ = { + isa = PBXGroup; + children = ( + 97CC3E7E1F77838700116D41 /* NotificationCenter+ObserveOnce.swift */, + ); + path = NotificationCenter; + sourceTree = ""; + }; 97CDC6D31F51E932006249FE /* Helpers */ = { isa = PBXGroup; children = ( @@ -285,9 +304,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 97AE29291E13C5E500C454C6 /* UIColor+Initializers.swift in Sources */, 97AE29281E13C5E500C454C6 /* GradientLoadingBar.swift in Sources */, 9725C8891E658B7200C79AEC /* Types.swift in Sources */, + 97CC3E801F77898E00116D41 /* UIColor+Initializers.swift in Sources */, + 97CC3E7F1F77838700116D41 /* NotificationCenter+ObserveOnce.swift in Sources */, 97AE292B1E13C5E500C454C6 /* GradientView.swift in Sources */, 97AE292A1E13C5E500C454C6 /* Durations.swift in Sources */, ); @@ -315,6 +335,7 @@ 97AE29181E13C5B400C454C6 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; @@ -369,6 +390,7 @@ 97AE29191E13C5B400C454C6 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; diff --git a/GradientLoadingBar/GradientLoadingBar.swift b/GradientLoadingBar/GradientLoadingBar.swift index 4dfbb68..72f8811 100644 --- a/GradientLoadingBar/GradientLoadingBar.swift +++ b/GradientLoadingBar/GradientLoadingBar.swift @@ -33,9 +33,6 @@ public class GradientLoadingBar { // View contain the gradient bar private let gradientView: GradientView - // Used to add "gradientView" once to key window on first call of "show()" - private var addedToKeyWindow = false - // Used to handle mutliple calls to show at the same time private var isVisible = false @@ -58,10 +55,12 @@ public class GradientLoadingBar { durations: durations, gradientColors: gradientColors ) + + addGradientViewToKeyWindow() } deinit { - if addedToKeyWindow { + if gradientView.superview != nil { gradientView.removeFromSuperview() } } @@ -69,16 +68,23 @@ public class GradientLoadingBar { // MARK: - Layout private func addGradientViewToKeyWindow() { + // If initializer called in "appDelegate" key window will not be available.. guard let keyWindow = UIApplication.shared.keyWindow else { - print("GradientLoadingBar: Couldn't add gradientView to keyWindow, as it is not available yet. Aborting.") + // .. so we setup an observer to add "gradientView" to key window when it's ready. + let notificationCenter = NotificationCenter.default + notificationCenter.observeOnce(forName: NSNotification.Name.UIWindowDidBecomeKey) { (_ notification) in + self.addGradientViewToKeyWindow() + } + + // Stop here and wait for observer to finish. return } - // Add gradient view to main window + // Add gradient view to main window.. gradientView.translatesAutoresizingMaskIntoConstraints = false keyWindow.addSubview(gradientView) - // Layout gradient view in main window + // .. and apply layout anchors. setupConstraints(keyWindow: keyWindow) } @@ -107,13 +113,6 @@ public class GradientLoadingBar { // MARK: - Show / Hide public func show() { - if !addedToKeyWindow { - addedToKeyWindow = true - - // Add "gradientView" to key window here, as window might not be available during intialization. - addGradientViewToKeyWindow() - } - if !isVisible { isVisible = true diff --git a/GradientLoadingBar/Helpers/Extensions/NotificationCenter/NotificationCenter+ObserveOnce.swift b/GradientLoadingBar/Helpers/Extensions/NotificationCenter/NotificationCenter+ObserveOnce.swift new file mode 100644 index 0000000..095302e --- /dev/null +++ b/GradientLoadingBar/Helpers/Extensions/NotificationCenter/NotificationCenter+ObserveOnce.swift @@ -0,0 +1,38 @@ +// +// NotificationCenter+ObserveOnce.swift +// GradientLoadingBar +// +// Created by Felix Mau on 24.09.17. +// Copyright © 2017 Felix Mau. All rights reserved. +// + +import Foundation + +// Source: https://gist.github.com/fxm90/68e2cc3cd6b63751c225b1e1249088cc +extension NotificationCenter { + + // Same parameters as "addObserver", except with default properties + func observeOnce( + forName: NSNotification.Name?, + object obj: Any? = nil, + queue: OperationQueue? = nil, + using block: @escaping (Notification) -> Swift.Void) + { + var observer: NSObjectProtocol? + observer = addObserver( + forName: forName, + object: obj, + queue: queue + ) { [weak self] (notification) in + guard let `self` = self else { + return + } + + // Call completion block and.. + block(notification) + + // .. directly remove observer! + self.removeObserver(observer!) + } + } +} diff --git a/GradientLoadingBar/Helpers/Extensions/UIColor+Initializers.swift b/GradientLoadingBar/Helpers/Extensions/UIColor/UIColor+Initializers.swift similarity index 100% rename from GradientLoadingBar/Helpers/Extensions/UIColor+Initializers.swift rename to GradientLoadingBar/Helpers/Extensions/UIColor/UIColor+Initializers.swift diff --git a/GradientLoadingBar/Views/GradientView.swift b/GradientLoadingBar/Views/GradientView.swift index 4752100..9755b1f 100644 --- a/GradientLoadingBar/Views/GradientView.swift +++ b/GradientLoadingBar/Views/GradientView.swift @@ -62,6 +62,9 @@ final class GradientView: UIView, CAAnimationDelegate { 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.. + // 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) diff --git a/readme.md b/readme.md index f8f8b40..b65f33a 100644 --- a/readme.md +++ b/readme.md @@ -59,7 +59,7 @@ After that you can use `GradientLoadingBar.sharedInstance()` as mentioned above. Check out [my GitHub Gist](https://gist.github.com/fxm90/698554e8335f34e0c6ab95194a4678fb) on how to easily use GradientLoadingBar with [PromiseKit](http://promisekit.org/). ### Version -1.1.2 +1.1.3 ### Author Felix Mau (contact(@)felix.hamburg)