From 4ef7dd0e196791f763591362886866b0c0396e40 Mon Sep 17 00:00:00 2001 From: Alexey Gerasimov Date: Fri, 30 Mar 2018 17:13:11 +0300 Subject: [PATCH] Delayed messages implemented --- CHANGELOG.md | 4 +++ LeadKitAdditions.podspec | 2 +- LeadKitAdditions.xcodeproj/project.pbxproj | 6 ++++ .../Model/PassCodeDelayedDescription.swift | 36 +++++++++++++++++++ .../View/BasePassCodeViewController.swift | 24 +++++++++++-- 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 Sources/Controllers/PassCode/Model/PassCodeDelayedDescription.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index 482049f..a67fb8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.2.2 + +- **Add**: `PassCodeDelayedDescription` to schedule error messages + ## 0.2.1 - **Fixed**: BasePassCodeViewController doesn't draw last dot filled diff --git a/LeadKitAdditions.podspec b/LeadKitAdditions.podspec index 34a1cbc..e2f50f3 100644 --- a/LeadKitAdditions.podspec +++ b/LeadKitAdditions.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "LeadKitAdditions" - s.version = "0.2.1" + s.version = "0.2.2" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKitAdditions" s.license = "Apache License, Version 2.0" diff --git a/LeadKitAdditions.xcodeproj/project.pbxproj b/LeadKitAdditions.xcodeproj/project.pbxproj index 9df7444..93c0bf5 100644 --- a/LeadKitAdditions.xcodeproj/project.pbxproj +++ b/LeadKitAdditions.xcodeproj/project.pbxproj @@ -69,6 +69,8 @@ ED0C34421F2906EC00FAE9FD /* ValidationItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33FD1F2906EC00FAE9FD /* ValidationItem.swift */; }; ED0C34431F2906EC00FAE9FD /* ValidationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33FE1F2906EC00FAE9FD /* ValidationService.swift */; }; ED0C34441F2906EC00FAE9FD /* ValidationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33FE1F2906EC00FAE9FD /* ValidationService.swift */; }; + EF5A43B1206E7A67003CED07 /* PassCodeDelayedDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF5A43B0206E7A67003CED07 /* PassCodeDelayedDescription.swift */; }; + EF5A43B2206E7A67003CED07 /* PassCodeDelayedDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF5A43B0206E7A67003CED07 /* PassCodeDelayedDescription.swift */; }; EFBD55921EBB9A980062AA63 /* LeadKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE698E61E968820000394B0 /* LeadKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ @@ -113,6 +115,7 @@ ED0C33FC1F2906EC00FAE9FD /* ValidationError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationError.swift; sourceTree = ""; }; ED0C33FD1F2906EC00FAE9FD /* ValidationItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationItem.swift; sourceTree = ""; }; ED0C33FE1F2906EC00FAE9FD /* ValidationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationService.swift; sourceTree = ""; }; + EF5A43B0206E7A67003CED07 /* PassCodeDelayedDescription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassCodeDelayedDescription.swift; sourceTree = ""; }; EFBD55701EBB87100062AA63 /* LeadKitAdditions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKitAdditions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EFBD55781EBB893F0062AA63 /* Info-iOS-Extensions.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS-Extensions.plist"; sourceTree = ""; }; EFBD55791EBB893F0062AA63 /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; @@ -233,6 +236,7 @@ isa = PBXGroup; children = ( ED0C33D91F2906EC00FAE9FD /* PassCodeConfiguration.swift */, + EF5A43B0206E7A67003CED07 /* PassCodeDelayedDescription.swift */, ED0C33DA1F2906EC00FAE9FD /* PassCodeError.swift */, ED0C33DB1F2906EC00FAE9FD /* PassCodeHolder.swift */, ED0C33DC1F2906EC00FAE9FD /* PassCodeHolderProtocol.swift */, @@ -571,6 +575,7 @@ ED0C34411F2906EC00FAE9FD /* ValidationItem.swift in Sources */, ED0C341F1F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift in Sources */, ED0C34091F2906EC00FAE9FD /* PassCodeConfiguration.swift in Sources */, + EF5A43B1206E7A67003CED07 /* PassCodeDelayedDescription.swift in Sources */, ED0C341D1F2906EC00FAE9FD /* Observable+Extensions.swift in Sources */, ED0C34191F2906EC00FAE9FD /* ApiErrorProtocol.swift in Sources */, ED0C34131F2906EC00FAE9FD /* BasePassCodeViewController.swift in Sources */, @@ -623,6 +628,7 @@ ED0C34121F2906EC00FAE9FD /* PassCodeValidationResult.swift in Sources */, ED0C34061F2906EC00FAE9FD /* BaseDateFormatter.swift in Sources */, ED0C34441F2906EC00FAE9FD /* ValidationService.swift in Sources */, + EF5A43B2206E7A67003CED07 /* PassCodeDelayedDescription.swift in Sources */, ED0C34341F2906EC00FAE9FD /* MaskFieldTextProxy.swift in Sources */, ED0C340C1F2906EC00FAE9FD /* PassCodeError.swift in Sources */, ED0C34161F2906EC00FAE9FD /* BasePassCodeViewModel.swift in Sources */, diff --git a/Sources/Controllers/PassCode/Model/PassCodeDelayedDescription.swift b/Sources/Controllers/PassCode/Model/PassCodeDelayedDescription.swift new file mode 100644 index 0000000..44f17f9 --- /dev/null +++ b/Sources/Controllers/PassCode/Model/PassCodeDelayedDescription.swift @@ -0,0 +1,36 @@ +// +// Copyright (c) 2018 Touch Instinct +// +// 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. +// + +import Foundation + +/// Describes attributed string and time interval that message should be displayed after +public struct PassCodeDelayedDescription { + + let delay: TimeInterval + let description: NSAttributedString + + public init(description: NSAttributedString, delay: TimeInterval = 0) { + self.description = description + self.delay = delay + } + +} diff --git a/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift b/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift index 26f8ba0..4cf79ab 100644 --- a/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift +++ b/Sources/Controllers/PassCode/View/BasePassCodeViewController.swift @@ -58,6 +58,7 @@ open class BasePassCodeViewController: UIViewController, ConfigurableController @IBOutlet private weak var dotStackView: UIStackView! public let disposeBag = DisposeBag() + private var delayedErrorDescriptions: Disposable? private lazy var fakeTextField: UITextField = { let fakeTextField = UITextField() @@ -191,9 +192,9 @@ open class BasePassCodeViewController: UIViewController, ConfigurableController } /// Override to change error description - open func errorDescription(for error: PassCodeError) -> NSAttributedString? { + open func errorDescription(for error: PassCodeError) -> [PassCodeDelayedDescription] { assertionFailure("You should override this method: errorDescription(for error: PassCodeError)") - return nil + return [] } /// Override to change action title text @@ -206,8 +207,25 @@ open class BasePassCodeViewController: UIViewController, ConfigurableController /// Call to show error open func showError(for error: PassCodeError) { - errorLabel?.attributedText = errorDescription(for: error) + let descriptionsObservables = errorDescription(for: error) + .sorted { $0.delay < $1.delay } + .map { [weak self] delayedDescription in + Observable + .interval(delayedDescription.delay, scheduler: MainScheduler.instance) + .take(1) + .do(onNext: { _ in + self?.errorLabel?.attributedText = delayedDescription.description + }) + } + + delayedErrorDescriptions?.dispose() + + errorLabel?.attributedText = nil errorLabel?.isHidden = false + + delayedErrorDescriptions = Observable + .merge(descriptionsObservables) + .subscribe() } /// Call to disappear error label