From 52751dc80126341fb8c50f2bdf5e6f6e9bfa422b Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Sun, 24 Jul 2022 15:25:28 +0300
Subject: [PATCH 01/17] feat: added initial alerts factory implementation
---
.../Alerts/Factories/AlertFactory.swift | 83 +++++++++++++++++++
.../Helpers/AlertDescriptor+Helpers.swift | 43 ++++++++++
.../UIAlertController+AlertPresentable.swift | 46 ++++++++++
.../Sources/Alerts/Helpers/View+Helpers.swift | 53 ++++++++++++
.../Sources/Alerts/Models/AlertAction.swift | 61 ++++++++++++++
.../Alerts/Models/AlertDescriptor.swift | 55 ++++++++++++
.../Alerts/Protocols/AlertPresentable.swift | 28 +++++++
.../Protocols/PresentationContext.swift | 27 ++++++
.../Alerts/Protocols/SwiftUIContext.swift | 43 ++++++++++
.../Alerts/Protocols/UIKitContext.swift | 25 ++++++
10 files changed, 464 insertions(+)
create mode 100644 TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
create mode 100644 TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift
create mode 100644 TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
create mode 100644 TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
create mode 100644 TIUIElements/Sources/Alerts/Models/AlertAction.swift
create mode 100644 TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift
create mode 100644 TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
create mode 100644 TIUIElements/Sources/Alerts/Protocols/PresentationContext.swift
create mode 100644 TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift
create mode 100644 TIUIElements/Sources/Alerts/Protocols/UIKitContext.swift
diff --git a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
new file mode 100644
index 00000000..37f7ac96
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
@@ -0,0 +1,83 @@
+//
+// Copyright (c) 2022 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 TISwiftUtils
+import UIKit
+
+open class AlertFactory {
+
+ open class func alert(title: String? = nil,
+ message: String? = nil,
+ tint: UIColor = .systemBlue,
+ actions: [AlertAction]) -> AlertDescriptor {
+
+ return AlertDescriptor(title: title,
+ message: message,
+ style: .alert,
+ tintColor: tint,
+ actions: actions)
+ }
+
+ open class func sheetAlert(title: String? = nil,
+ message: String? = nil,
+ tint: UIColor = .systemBlue,
+ actions: [AlertAction]) -> AlertDescriptor {
+
+ return AlertDescriptor(title: title,
+ message: message,
+ style: .actionSheet,
+ tintColor: tint,
+ actions: actions)
+ }
+
+ open class func okAlert(title: String? = nil,
+ message: String? = nil,
+ tint: UIColor = .systemBlue) -> AlertDescriptor {
+ AlertDescriptor(title: title,
+ message: message,
+ style: .alert,
+ tintColor: tint,
+ actions: [.okAction])
+ }
+
+ open class func retryAlert(title: String? = nil,
+ message: String? = nil,
+ cancelTitle: String = "Cancel",
+ tint: UIColor = .systemBlue,
+ retryAction: VoidClosure? = nil) -> AlertDescriptor {
+ AlertDescriptor(title: title,
+ message: message,
+ tintColor: tint,
+ actions: [.cancelAction(cancelTitle),
+ AlertAction(title: "Retry", action: retryAction)])
+ }
+}
+
+private extension AlertAction {
+ static var okAction: AlertAction {
+ AlertAction(title: "Ok", action: {})
+ }
+
+ static func cancelAction(_ title: String = "Cancel") -> AlertAction {
+ AlertAction(title: title, style: .cancel, action: {})
+ }
+}
diff --git a/TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift b/TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift
new file mode 100644
index 00000000..9166ea38
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2022 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 TISwiftUtils
+import UIKit
+
+extension AlertDescriptor {
+ public func present(on context: PresentationContext, completion: VoidClosure? = nil) {
+ let alertFactory: Closure = { configuration in
+ UIAlertController(title: configuration.title,
+ message: configuration.message,
+ preferredStyle: configuration.style)
+ .configured(with: configuration)
+ }
+
+ present(on: context, alertViewFactory: alertFactory, completion: completion)
+ }
+
+ public func present(on context: PresentationContext,
+ alertViewFactory: Closure,
+ completion: VoidClosure? = nil) {
+ alertViewFactory(self).present(on: context, completion: completion)
+ }
+}
diff --git a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
new file mode 100644
index 00000000..789c778a
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
@@ -0,0 +1,46 @@
+//
+// Copyright (c) 2021 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 TISwiftUtils
+import UIKit
+
+extension UIAlertController {
+
+ @discardableResult
+ public func configured(with configuration: AlertDescriptor) -> Self {
+ title = configuration.title
+ message = configuration.message
+ view.tintColor = configuration.tintColor
+
+ for action in configuration.actions {
+ addAction(action.asUIAlertAction)
+ }
+
+ return self
+ }
+}
+
+extension UIAlertController: AlertPresentable {
+ public func present(on context: PresentationContext, completion: VoidClosure?) {
+ context.present(self, animated: true, completion: completion)
+ }
+}
diff --git a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
new file mode 100644
index 00000000..b7184e68
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2021 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 TISwiftUtils
+import SwiftUI
+
+@available(iOS 13.0, *)
+public extension View {
+ func alert(isPresented: Binding,
+ on context: PresentationContext,
+ alert: AlertDescriptor) -> some View {
+
+ if isPresented.wrappedValue {
+ alert.present(on: context) {
+ isPresented.wrappedValue = false
+ }
+ }
+
+ return self
+ }
+
+ func alert(isPresented: Binding,
+ on context: PresentationContext,
+ alertViewFactory: ResultClosure) -> some View {
+
+ if isPresented.wrappedValue {
+ alertViewFactory().present(on: context) {
+ isPresented.wrappedValue = false
+ }
+ }
+
+ return self
+ }
+}
diff --git a/TIUIElements/Sources/Alerts/Models/AlertAction.swift b/TIUIElements/Sources/Alerts/Models/AlertAction.swift
new file mode 100644
index 00000000..ef6f43ca
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Models/AlertAction.swift
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2021 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 TISwiftUtils
+import UIKit
+
+// struct describe alert button information
+public struct AlertAction: Identifiable {
+
+ public let id = UUID()
+
+ /// Alert button title
+ public let title: String
+
+ /// Alert button style
+ public let style: UIAlertAction.Style
+
+ /// Alert button action
+ public let action: VoidClosure?
+
+ init(title: String, style: UIAlertAction.Style = .default, action: VoidClosure? = nil) {
+ self.title = title
+ self.style = style
+ self.action = action
+ }
+}
+
+// MARK: - AlertAction + Equatable
+
+extension AlertAction: Equatable {
+ public static func == (lhs: AlertAction, rhs: AlertAction) -> Bool {
+ return false
+ }
+}
+
+// MARK: - AlertAction + Helpers
+
+extension AlertAction {
+ var asUIAlertAction: UIAlertAction {
+ UIAlertAction(title: title, style: style, handler: { _ in action?() })
+ }
+}
diff --git a/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift b/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift
new file mode 100644
index 00000000..cd07687c
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift
@@ -0,0 +1,55 @@
+//
+// Copyright (c) 2021 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 UIKit
+
+/// Struct describes alert data
+public struct AlertDescriptor {
+
+ /// Alert title
+ public let title: String?
+
+ /// Alert message
+ public let message: String?
+
+ /// Alert style
+ public let style: UIAlertController.Style
+
+ /// Alert tint color
+ public let tintColor: UIColor
+
+ /// Alert actions
+ public let actions: [AlertAction]
+
+ public init(title: String? = nil,
+ message: String? = nil,
+ style: UIAlertController.Style = .alert,
+ tintColor: UIColor = .systemBlue,
+ actions: [AlertAction] = []) {
+
+ self.title = title
+ self.message = message
+ self.style = style
+ self.tintColor = tintColor
+ self.actions = actions
+ }
+}
diff --git a/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift b/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
new file mode 100644
index 00000000..9e8c3488
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
@@ -0,0 +1,28 @@
+//
+// Copyright (c) 2022 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 TISwiftUtils
+import Foundation
+
+public protocol AlertPresentable {
+ func present(on context: PresentationContext, completion: VoidClosure?)
+}
diff --git a/TIUIElements/Sources/Alerts/Protocols/PresentationContext.swift b/TIUIElements/Sources/Alerts/Protocols/PresentationContext.swift
new file mode 100644
index 00000000..caf5028b
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Protocols/PresentationContext.swift
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2022 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 UIKit
+
+public protocol PresentationContext {
+ func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?)
+}
diff --git a/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift b/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift
new file mode 100644
index 00000000..9a812b63
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2022 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 SwiftUI
+
+@available(iOS 13, *)
+public protocol SwiftUIContext: PresentationContext {
+ var presentedViewController: UIViewController? { get }
+}
+
+@available(iOS 13, *)
+extension SwiftUIContext {
+ var presentedViewController: UIViewController? {
+ UIApplication.shared.windows.first?.rootViewController?.presentedViewController
+ }
+
+ func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?) {
+ guard let viewController = presentedViewController else {
+ return
+ }
+
+ viewController.present(viewControllerToPresent, animated: flag, completion: completion)
+ }
+}
diff --git a/TIUIElements/Sources/Alerts/Protocols/UIKitContext.swift b/TIUIElements/Sources/Alerts/Protocols/UIKitContext.swift
new file mode 100644
index 00000000..5958824a
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Protocols/UIKitContext.swift
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 2022 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 UIKit
+
+public protocol UIKitContext: PresentationContext { }
From 000e88f98af234fc196ac9aff2a8e055b2eb4ccd Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Sun, 24 Jul 2022 15:34:09 +0300
Subject: [PATCH 02/17] fix: small access control fixes
---
TIUIElements/Sources/Alerts/Models/AlertAction.swift | 2 +-
TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/TIUIElements/Sources/Alerts/Models/AlertAction.swift b/TIUIElements/Sources/Alerts/Models/AlertAction.swift
index ef6f43ca..ce2a92a0 100644
--- a/TIUIElements/Sources/Alerts/Models/AlertAction.swift
+++ b/TIUIElements/Sources/Alerts/Models/AlertAction.swift
@@ -37,7 +37,7 @@ public struct AlertAction: Identifiable {
/// Alert button action
public let action: VoidClosure?
- init(title: String, style: UIAlertAction.Style = .default, action: VoidClosure? = nil) {
+ public init(title: String, style: UIAlertAction.Style = .default, action: VoidClosure? = nil) {
self.title = title
self.style = style
self.action = action
diff --git a/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift b/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift
index 9a812b63..7c998fc0 100644
--- a/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift
+++ b/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift
@@ -28,7 +28,7 @@ public protocol SwiftUIContext: PresentationContext {
}
@available(iOS 13, *)
-extension SwiftUIContext {
+public extension SwiftUIContext {
var presentedViewController: UIViewController? {
UIApplication.shared.windows.first?.rootViewController?.presentedViewController
}
From c223a026f26fd02bf124e90d86397777c204928c Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Mon, 25 Jul 2022 14:08:01 +0300
Subject: [PATCH 03/17] fix: custom alerts configuration for sui + version
control changes
---
TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift | 5 +++--
TIUIElements/Sources/Alerts/Models/AlertAction.swift | 7 ++++++-
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
index b7184e68..2327e244 100644
--- a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
+++ b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
@@ -40,10 +40,11 @@ public extension View {
func alert(isPresented: Binding,
on context: PresentationContext,
- alertViewFactory: ResultClosure) -> some View {
+ alertDescriptor descriptor: AlertDescriptor,
+ alertViewFactory: Closure) -> some View {
if isPresented.wrappedValue {
- alertViewFactory().present(on: context) {
+ alertViewFactory(descriptor).present(on: context) {
isPresented.wrappedValue = false
}
}
diff --git a/TIUIElements/Sources/Alerts/Models/AlertAction.swift b/TIUIElements/Sources/Alerts/Models/AlertAction.swift
index ce2a92a0..229d3f0a 100644
--- a/TIUIElements/Sources/Alerts/Models/AlertAction.swift
+++ b/TIUIElements/Sources/Alerts/Models/AlertAction.swift
@@ -24,7 +24,7 @@ import TISwiftUtils
import UIKit
// struct describe alert button information
-public struct AlertAction: Identifiable {
+public struct AlertAction {
public let id = UUID()
@@ -52,6 +52,11 @@ extension AlertAction: Equatable {
}
}
+// MARK: - AlertAction + Identifiable
+
+@available(iOS 13, *)
+extension AlertAction: Identifiable { }
+
// MARK: - AlertAction + Helpers
extension AlertAction {
From 37b722426415ca459110fae9f5e11abdd73fa619 Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Mon, 25 Jul 2022 15:34:04 +0300
Subject: [PATCH 04/17] feat: added default localization provider for actions +
documentation added
---
.../Alerts/Factories/AlertFactory.swift | 135 +++++++++++++-----
.../UIAlertController+AlertPresentable.swift | 2 +-
.../Sources/Alerts/Helpers/View+Helpers.swift | 14 +-
.../Sources/Alerts/Models/AlertAction.swift | 2 +-
.../Alerts/Models/AlertDescriptor.swift | 2 +-
.../DefaultAlertLocalizationProvider.swift | 53 +++++++
.../Protocols/AlertLocalizationProvider.swift | 29 ++++
7 files changed, 196 insertions(+), 41 deletions(-)
create mode 100644 TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift
create mode 100644 TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift
diff --git a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
index 37f7ac96..6f5d88b6 100644
--- a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
+++ b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
@@ -25,59 +25,120 @@ import UIKit
open class AlertFactory {
- open class func alert(title: String? = nil,
- message: String? = nil,
- tint: UIColor = .systemBlue,
- actions: [AlertAction]) -> AlertDescriptor {
+ public var localizationProvider: AlertLocalizationProvider
- return AlertDescriptor(title: title,
- message: message,
- style: .alert,
- tintColor: tint,
- actions: actions)
+ public init(localizationProvider: AlertLocalizationProvider = DefaultAlertLocalizationProvider()) {
+ self.localizationProvider = localizationProvider
}
- open class func sheetAlert(title: String? = nil,
- message: String? = nil,
- tint: UIColor = .systemBlue,
- actions: [AlertAction]) -> AlertDescriptor {
+ /// Provides general alert description.
+ /// - Parameters:
+ /// - title: A text string used as the title of the alert.
+ /// - message: A text string used as the message of the alert.
+ /// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue.
+ /// - actions: An array of actions of the alert.
+ /// - Returns: Alert descriptor, which can be used to present alert view.
+ open func alert(title: String? = nil,
+ message: String? = nil,
+ tint: UIColor = .systemBlue,
+ actions: [AlertAction]) -> AlertDescriptor {
- return AlertDescriptor(title: title,
- message: message,
- style: .actionSheet,
- tintColor: tint,
- actions: actions)
+ AlertDescriptor(title: title,
+ message: message,
+ tintColor: tint,
+ actions: actions)
}
- open class func okAlert(title: String? = nil,
+ /// Provides general sheet alert description.
+ /// - Parameters:
+ /// - title: A text string used as the title of the sheet alert.
+ /// - message: A text string used as the message of the sheet alert.
+ /// - tint: A color used as a tint color of the sheet alert. Default color is UIColor.systemBlue.
+ /// - actions: An array of actions of the sheet alert.
+ /// - Returns: Alert descriptor, which can be used to present sheet alert view.
+ open func sheetAlert(title: String? = nil,
+ message: String? = nil,
+ tint: UIColor = .systemBlue,
+ actions: [AlertAction]) -> AlertDescriptor {
+
+ AlertDescriptor(title: title,
+ message: message,
+ style: .actionSheet,
+ tintColor: tint,
+ actions: actions)
+ }
+
+ /// Provides ok type alert description.
+ /// - Parameters:
+ /// - title: A text string used as the title of the alert.
+ /// - message: A text string used as the message of the alert.
+ /// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue.
+ /// - Returns: Alert descriptor, which can be used to present alert view.
+ open func okAlert(title: String? = nil,
+ message: String? = nil,
+ tint: UIColor = .systemBlue) -> AlertDescriptor {
+
+ AlertDescriptor(title: title,
+ message: message,
+ tintColor: tint,
+ actions: [.simpleAction(localizationProvider.okTitle)])
+ }
+
+ /// Provides retry type alert description.
+ /// - Parameters:
+ /// - title: A text string used as the title of the alert.
+ /// - message: A text string used as the message of the alert.
+ /// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue.
+ /// - retryAction: A closure called by tapping on the retry button of the alert.
+ /// - Returns: Alert descriptor, which can be used to present alert view.
+ open func retryAlert(title: String? = nil,
+ message: String? = nil,
+ tint: UIColor = .systemBlue,
+ retryAction: VoidClosure? = nil) -> AlertDescriptor {
+
+ AlertDescriptor(title: title,
+ message: message,
+ tintColor: tint,
+ actions: [
+ .cancelAction(localizationProvider.cancelTitle),
+ .init(title: localizationProvider.retryTitle, action: retryAction)
+ ])
+ }
+
+ /// Provides dialogue type alert description. Dialogue type alert containes to buttons: Yes and No.
+ /// - Parameters:
+ /// - title: A text string used as the title of the alert.
+ /// - message: A text string used as the message of the alert.
+ /// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue.
+ /// - yesAction: A closure called by tapping on the yes button of the alert.
+ /// - noAction: A closure called by tapping on the no button of the alert.
+ /// - Returns: Alert descriptor, which can be used to present alert view.
+ open func dialogueAlert(title: String? = nil,
message: String? = nil,
- tint: UIColor = .systemBlue) -> AlertDescriptor {
- AlertDescriptor(title: title,
- message: message,
- style: .alert,
- tintColor: tint,
- actions: [.okAction])
- }
+ tint: UIColor = .systemBlue,
+ yesAction: VoidClosure? = nil,
+ noAction: VoidClosure? = nil) -> AlertDescriptor {
- open class func retryAlert(title: String? = nil,
- message: String? = nil,
- cancelTitle: String = "Cancel",
- tint: UIColor = .systemBlue,
- retryAction: VoidClosure? = nil) -> AlertDescriptor {
AlertDescriptor(title: title,
message: message,
tintColor: tint,
- actions: [.cancelAction(cancelTitle),
- AlertAction(title: "Retry", action: retryAction)])
+ actions: [
+ .init(title: localizationProvider.yesTitle, style: .destructive, action: yesAction),
+ .init(title: localizationProvider.noTitle, action: noAction)
+ ])
}
}
+// MARK: - AlertAction + Helpers
+
private extension AlertAction {
- static var okAction: AlertAction {
- AlertAction(title: "Ok", action: {})
+ static func simpleAction(_ title: String,
+ style: UIAlertAction.Style = .default) -> AlertAction {
+
+ AlertAction(title: title, style: style, action: nil)
}
- static func cancelAction(_ title: String = "Cancel") -> AlertAction {
- AlertAction(title: title, style: .cancel, action: {})
+ static func cancelAction(_ title: String) -> AlertAction {
+ .simpleAction(title, style: .cancel)
}
}
diff --git a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
index 789c778a..4a718c09 100644
--- a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
+++ b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2021 Touch Instinct
+// Copyright (c) 2022 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
diff --git a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
index 2327e244..6af75ec1 100644
--- a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
+++ b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2021 Touch Instinct
+// Copyright (c) 2022 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
@@ -25,6 +25,12 @@ import SwiftUI
@available(iOS 13.0, *)
public extension View {
+
+ /// Presents an alert with a description on a context when a given condition is true.
+ /// - Parameters:
+ /// - isPresented: A binding to a Boolean value that determines whether to present the alert. When the user presses or taps one of the alert’s actions, the system sets this value to false and dismisses.
+ /// - context: The view that will show the alert
+ /// - alert: Descriptor of the alert.
func alert(isPresented: Binding,
on context: PresentationContext,
alert: AlertDescriptor) -> some View {
@@ -38,6 +44,12 @@ public extension View {
return self
}
+ /// Presents an alert with a description on a context with custom configuration of the alert when a given condition is true.
+ /// - Parameters:
+ /// - isPresented: A binding to a Boolean value that determines whether to present the alert. When the user presses or taps one of the alert’s actions, the system sets this value to false and dismisses.
+ /// - context: The view that will show the alert
+ /// - descriptor: Descriptor of the alert.
+ /// - alertViewFactory: A closure called to configure custom alert.
func alert(isPresented: Binding,
on context: PresentationContext,
alertDescriptor descriptor: AlertDescriptor,
diff --git a/TIUIElements/Sources/Alerts/Models/AlertAction.swift b/TIUIElements/Sources/Alerts/Models/AlertAction.swift
index 229d3f0a..c90b8996 100644
--- a/TIUIElements/Sources/Alerts/Models/AlertAction.swift
+++ b/TIUIElements/Sources/Alerts/Models/AlertAction.swift
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2021 Touch Instinct
+// Copyright (c) 2022 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
diff --git a/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift b/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift
index cd07687c..2efb8190 100644
--- a/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift
+++ b/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2021 Touch Instinct
+// Copyright (c) 2022 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
diff --git a/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift b/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift
new file mode 100644
index 00000000..a1a7084c
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2022 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
+
+/// Provide default localization for alerts' buttons
+open class DefaultAlertLocalizationProvider: AlertLocalizationProvider {
+
+ public private(set) var bundle: Bundle
+
+ public init(bundle: Bundle = .main) {
+ self.bundle = bundle
+ }
+
+ open var okTitle: String {
+ bundle.localizedString(forKey: "common_ok", value: "Ок", table: nil)
+ }
+
+ open var cancelTitle: String {
+ bundle.localizedString(forKey: "common_cancel", value: "Отмена", table: nil)
+ }
+
+ open var retryTitle: String {
+ bundle.localizedString(forKey: "common_retry", value: "Повторить", table: nil)
+ }
+
+ open var yesTitle: String {
+ bundle.localizedString(forKey: "common_yes", value: "Да", table: nil)
+ }
+
+ open var noTitle: String {
+ bundle.localizedString(forKey: "common_no", value: "Нет", table: nil)
+ }
+}
diff --git a/TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift b/TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift
new file mode 100644
index 00000000..98795b27
--- /dev/null
+++ b/TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift
@@ -0,0 +1,29 @@
+//
+// Copyright (c) 2022 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.
+//
+
+public protocol AlertLocalizationProvider {
+ var okTitle: String { get }
+ var cancelTitle: String { get }
+ var retryTitle: String { get }
+ var yesTitle: String { get }
+ var noTitle: String { get }
+}
From b96478c248d0773f0e9cd97903cf1d1bc61098a2 Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Mon, 25 Jul 2022 15:53:38 +0300
Subject: [PATCH 05/17] fix: dialogue type alert actions' styles
---
TIUIElements/Sources/Alerts/Factories/AlertFactory.swift | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
index 6f5d88b6..79c62efc 100644
--- a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
+++ b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
@@ -123,8 +123,8 @@ open class AlertFactory {
message: message,
tintColor: tint,
actions: [
- .init(title: localizationProvider.yesTitle, style: .destructive, action: yesAction),
- .init(title: localizationProvider.noTitle, action: noAction)
+ .init(title: localizationProvider.yesTitle, action: yesAction),
+ .init(title: localizationProvider.noTitle, style: .destructive, action: noAction)
])
}
}
From 24d1384e0f464638b8c24440a139f73a7ae94e62 Mon Sep 17 00:00:00 2001
From: Nikita Semenov <69932531+castlele@users.noreply.github.com>
Date: Mon, 25 Jul 2022 16:36:32 +0300
Subject: [PATCH 06/17] doc: implement documentation for alerts api
---
TIUIElements/README.md | 76 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/TIUIElements/README.md b/TIUIElements/README.md
index 0bafa5af..91e83ced 100644
--- a/TIUIElements/README.md
+++ b/TIUIElements/README.md
@@ -126,7 +126,81 @@ class ViewController: UITableViewController, CollapsibleViewsContainer {
-
+
+# AlertsFactory
+Use to present alerts in a few lines of code. Can be used for UIKit and SwiftUI
+> You can initialize `AlertsFactory` with your own *LocalizationProvider* or use `DefaultAlertLocalizationProvider`
+
+## Your view or view controller must implement PresentationContext protocol
+There are `UIKitContext` and `SwiftUIContext` protocols that are designed to make it easier to work with `PresentationContext` protocol. By default, no changes need to be made for UIKit view controllers and SwiftUI views to make them conform to these protocols
+
+## Custom alerts
+```swift
+// Presents alert
+func presentAlert() {
+ factory
+ .alert(title: "Alert's title",
+ message: "Alert's message",
+ tint: .systemBlue,
+ actions: [
+ AlertAction(title: "Ok", style: .default, action: nil),
+ AlertAction(title: "Cancel", style: .cancel, action: nil)
+ ])
+ .present(on: self)
+}
+
+// Presents sheet alert
+func presentSheetAlert() {
+ factory
+ .sheetAlert(title: "Alert's title",
+ message: "Alert's message",
+ tint: .systemBlue,
+ actions: [
+ AlertAction(title: "Ok", style: .default, action: nil),
+ AlertAction(title: "Cancel", style: .cancel, action: nil)
+ ])
+ .present(on: self)
+}
+```
+
+## Default alerts
+```swift
+// Ok alert
+func presentOkAlert() {
+ factory
+ .okAlert(title: "Title", message: "Message")
+ .present(on: self)
+}
+
+// Retry alert
+func presentRetryAlert() {
+ factory
+ .retryAlert(title: "Title", message: "Message") { [weak self] in
+ self?.presentOkAlert()
+ }
+ .present(on: self)
+}
+
+// Dialogue alert
+func presentDialogueAlert() {
+ factory
+ .dialogueAlert(title: "Title", message: "Message")
+ .present(on: self)
+}
+```
+
+## SwiftUI alerts
+```swift
+var body: some View {
+ Button("Show custom alert with binding property") {
+ alertDescription = factory.okAlert(title: "Title", message: "Message")
+ isPresentedCustomAlert = true
+ }
+ }
+ .alert(isPresented: $isPresentedAlert, on: self, alert: alertDescription)
+}
+```
+
# Installation via SPM
You can install this framework as a target of LeadKit.
From 693843bb70e76856ac2806f2a7369f5e0099874e Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Mon, 25 Jul 2022 19:01:55 +0300
Subject: [PATCH 07/17] fix: code review notes
---
CHANGELOG.md | 4 ++++
LeadKit.podspec | 2 +-
TIAppleMapUtils/TIAppleMapUtils.podspec | 2 +-
TIAuth/TIAuth.podspec | 2 +-
TIFoundationUtils/TIFoundationUtils.podspec | 2 +-
TIGoogleMapUtils/TIGoogleMapUtils.podspec | 2 +-
TIKeychainUtils/TIKeychainUtils.podspec | 2 +-
TIMapUtils/TIMapUtils.podspec | 2 +-
TIMoyaNetworking/TIMoyaNetworking.podspec | 2 +-
TINetworking/TINetworking.podspec | 2 +-
TINetworkingCache/TINetworkingCache.podspec | 2 +-
TIPagination/TIPagination.podspec | 2 +-
TISwiftUICore/TISwiftUICore.podspec | 2 +-
TISwiftUtils/TISwiftUtils.podspec | 2 +-
TITableKitUtils/TITableKitUtils.podspec | 2 +-
TITransitions/TITransitions.podspec | 2 +-
TIUIElements/README.md | 2 +-
.../Alerts/Factories/AlertFactory.swift | 1 -
.../Helpers/AlertDescriptor+Helpers.swift | 6 +++---
.../UIAlertController+AlertPresentable.swift | 8 ++++----
.../Sources/Alerts/Helpers/View+Helpers.swift | 4 ++--
.../DefaultAlertLocalizationProvider.swift | 2 +-
.../Alerts/Protocols/AlertPresentable.swift | 2 +-
...t.swift => AlertPresentationContext.swift} | 5 +++--
...ontext.swift => SwiftUIAlertContext.swift} | 19 ++++++-------------
...tContext.swift => UIKitAlertContext.swift} | 2 +-
TIUIElements/TIUIElements.podspec | 2 +-
TIUIKitCore/TIUIKitCore.podspec | 2 +-
TIYandexMapUtils/TIYandexMapUtils.podspec | 2 +-
29 files changed, 44 insertions(+), 47 deletions(-)
rename TIUIElements/Sources/Alerts/Protocols/{PresentationContext.swift => AlertPresentationContext.swift} (91%)
rename TIUIElements/Sources/Alerts/Protocols/{SwiftUIContext.swift => SwiftUIAlertContext.swift} (70%)
rename TIUIElements/Sources/Alerts/Protocols/{UIKitContext.swift => UIKitAlertContext.swift} (94%)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86e1929f..b9477b9b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+### 1.24.0
+
+- **Add**: `AlertFactory` for presenting alerts in SwiftUI and UIKit.
+
### 1.22.0
- **Update**: Asynchronous request preprocessing
diff --git a/LeadKit.podspec b/LeadKit.podspec
index 4d42224b..cb70b7b8 100644
--- a/LeadKit.podspec
+++ b/LeadKit.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "LeadKit"
- s.version = "1.22.0"
+ s.version = "1.24.0"
s.summary = "iOS framework with a bunch of tools for rapid development"
s.homepage = "https://github.com/TouchInstinct/LeadKit"
s.license = "Apache License, Version 2.0"
diff --git a/TIAppleMapUtils/TIAppleMapUtils.podspec b/TIAppleMapUtils/TIAppleMapUtils.podspec
index 59ba157b..b3f84580 100644
--- a/TIAppleMapUtils/TIAppleMapUtils.podspec
+++ b/TIAppleMapUtils/TIAppleMapUtils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIAppleMapUtils'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Set of helpers for map objects clustering and interacting using Apple MapKit.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIAuth/TIAuth.podspec b/TIAuth/TIAuth.podspec
index 3266d6e5..9bc961f6 100644
--- a/TIAuth/TIAuth.podspec
+++ b/TIAuth/TIAuth.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIAuth'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Login, registration, confirmation and other related actions'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIFoundationUtils/TIFoundationUtils.podspec b/TIFoundationUtils/TIFoundationUtils.podspec
index 07b02a63..39fd763a 100644
--- a/TIFoundationUtils/TIFoundationUtils.podspec
+++ b/TIFoundationUtils/TIFoundationUtils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIFoundationUtils'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Set of helpers for Foundation framework classes.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIGoogleMapUtils/TIGoogleMapUtils.podspec b/TIGoogleMapUtils/TIGoogleMapUtils.podspec
index ea5456a5..68ad58e9 100644
--- a/TIGoogleMapUtils/TIGoogleMapUtils.podspec
+++ b/TIGoogleMapUtils/TIGoogleMapUtils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIGoogleMapUtils'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Set of helpers for map objects clustering and interacting using Google Maps SDK.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIKeychainUtils/TIKeychainUtils.podspec b/TIKeychainUtils/TIKeychainUtils.podspec
index d099e240..f68e2a3b 100644
--- a/TIKeychainUtils/TIKeychainUtils.podspec
+++ b/TIKeychainUtils/TIKeychainUtils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIKeychainUtils'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Set of helpers for Keychain classes.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIMapUtils/TIMapUtils.podspec b/TIMapUtils/TIMapUtils.podspec
index ef157380..29fb1077 100644
--- a/TIMapUtils/TIMapUtils.podspec
+++ b/TIMapUtils/TIMapUtils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIMapUtils'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Set of helpers for map objects clustering and interacting.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIMoyaNetworking/TIMoyaNetworking.podspec b/TIMoyaNetworking/TIMoyaNetworking.podspec
index d4061461..9ceeffb5 100644
--- a/TIMoyaNetworking/TIMoyaNetworking.podspec
+++ b/TIMoyaNetworking/TIMoyaNetworking.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIMoyaNetworking'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Moya + Swagger network service.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TINetworking/TINetworking.podspec b/TINetworking/TINetworking.podspec
index 1749684d..f6631a9a 100644
--- a/TINetworking/TINetworking.podspec
+++ b/TINetworking/TINetworking.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TINetworking'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Swagger-frendly networking layer helpers.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TINetworkingCache/TINetworkingCache.podspec b/TINetworkingCache/TINetworkingCache.podspec
index fa086f5a..a12b2177 100644
--- a/TINetworkingCache/TINetworkingCache.podspec
+++ b/TINetworkingCache/TINetworkingCache.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TINetworkingCache'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Caching results of EndpointRequests.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIPagination/TIPagination.podspec b/TIPagination/TIPagination.podspec
index be2e9143..eea01a31 100644
--- a/TIPagination/TIPagination.podspec
+++ b/TIPagination/TIPagination.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIPagination'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Generic pagination component.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TISwiftUICore/TISwiftUICore.podspec b/TISwiftUICore/TISwiftUICore.podspec
index 7c8dde9f..fd2b61a2 100644
--- a/TISwiftUICore/TISwiftUICore.podspec
+++ b/TISwiftUICore/TISwiftUICore.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TISwiftUICore'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Core UI elements: protocols, views and helpers..'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TISwiftUtils/TISwiftUtils.podspec b/TISwiftUtils/TISwiftUtils.podspec
index f22e5a1e..9aebb85f 100644
--- a/TISwiftUtils/TISwiftUtils.podspec
+++ b/TISwiftUtils/TISwiftUtils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TISwiftUtils'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Bunch of useful helpers for Swift development.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TITableKitUtils/TITableKitUtils.podspec b/TITableKitUtils/TITableKitUtils.podspec
index d808aba8..20966a66 100644
--- a/TITableKitUtils/TITableKitUtils.podspec
+++ b/TITableKitUtils/TITableKitUtils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TITableKitUtils'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Set of helpers for TableKit classes.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TITransitions/TITransitions.podspec b/TITransitions/TITransitions.podspec
index e1dcf910..1cb39350 100644
--- a/TITransitions/TITransitions.podspec
+++ b/TITransitions/TITransitions.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TITransitions'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Set of custom transitions to present controller. '
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIUIElements/README.md b/TIUIElements/README.md
index 91e83ced..9eea58ad 100644
--- a/TIUIElements/README.md
+++ b/TIUIElements/README.md
@@ -132,7 +132,7 @@ Use to present alerts in a few lines of code. Can be used for UIKit and SwiftUI
> You can initialize `AlertsFactory` with your own *LocalizationProvider* or use `DefaultAlertLocalizationProvider`
## Your view or view controller must implement PresentationContext protocol
-There are `UIKitContext` and `SwiftUIContext` protocols that are designed to make it easier to work with `PresentationContext` protocol. By default, no changes need to be made for UIKit view controllers and SwiftUI views to make them conform to these protocols
+There are `UIKitAlertContext` and `SwiftUIAlertContext` protocols that are designed to make it easier to work with `AlertPresentationContext` protocol. By default, no changes need to be made for UIKit view controllers to make them conform to `UIKitAlertContext`.
## Custom alerts
```swift
diff --git a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
index 79c62efc..9a50f530 100644
--- a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
+++ b/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
@@ -24,7 +24,6 @@ import TISwiftUtils
import UIKit
open class AlertFactory {
-
public var localizationProvider: AlertLocalizationProvider
public init(localizationProvider: AlertLocalizationProvider = DefaultAlertLocalizationProvider()) {
diff --git a/TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift b/TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift
index 9166ea38..192f504e 100644
--- a/TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift
+++ b/TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift
@@ -23,8 +23,8 @@
import TISwiftUtils
import UIKit
-extension AlertDescriptor {
- public func present(on context: PresentationContext, completion: VoidClosure? = nil) {
+public extension AlertDescriptor {
+ func present(on context: AlertPresentationContext, completion: VoidClosure? = nil) {
let alertFactory: Closure = { configuration in
UIAlertController(title: configuration.title,
message: configuration.message,
@@ -35,7 +35,7 @@ extension AlertDescriptor {
present(on: context, alertViewFactory: alertFactory, completion: completion)
}
- public func present(on context: PresentationContext,
+ func present(on context: AlertPresentationContext,
alertViewFactory: Closure,
completion: VoidClosure? = nil) {
alertViewFactory(self).present(on: context, completion: completion)
diff --git a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
index 4a718c09..a2a5458a 100644
--- a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
+++ b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
@@ -20,13 +20,13 @@
// THE SOFTWARE.
//
-import TISwiftUtils
+import typealias TISwiftUtils.VoidClosure
import UIKit
-extension UIAlertController {
+public extension UIAlertController {
@discardableResult
- public func configured(with configuration: AlertDescriptor) -> Self {
+ func configured(with configuration: AlertDescriptor) -> Self {
title = configuration.title
message = configuration.message
view.tintColor = configuration.tintColor
@@ -40,7 +40,7 @@ extension UIAlertController {
}
extension UIAlertController: AlertPresentable {
- public func present(on context: PresentationContext, completion: VoidClosure?) {
+ public func present(on context: AlertPresentationContext, completion: VoidClosure?) {
context.present(self, animated: true, completion: completion)
}
}
diff --git a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
index 6af75ec1..2f9bea2d 100644
--- a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
+++ b/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
@@ -32,7 +32,7 @@ public extension View {
/// - context: The view that will show the alert
/// - alert: Descriptor of the alert.
func alert(isPresented: Binding,
- on context: PresentationContext,
+ on context: AlertPresentationContext,
alert: AlertDescriptor) -> some View {
if isPresented.wrappedValue {
@@ -51,7 +51,7 @@ public extension View {
/// - descriptor: Descriptor of the alert.
/// - alertViewFactory: A closure called to configure custom alert.
func alert(isPresented: Binding,
- on context: PresentationContext,
+ on context: AlertPresentationContext,
alertDescriptor descriptor: AlertDescriptor,
alertViewFactory: Closure) -> some View {
diff --git a/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift b/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift
index a1a7084c..9b506998 100644
--- a/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift
+++ b/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift
@@ -25,7 +25,7 @@ import Foundation
/// Provide default localization for alerts' buttons
open class DefaultAlertLocalizationProvider: AlertLocalizationProvider {
- public private(set) var bundle: Bundle
+ public var bundle: Bundle
public init(bundle: Bundle = .main) {
self.bundle = bundle
diff --git a/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift b/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
index 9e8c3488..142f5b89 100644
--- a/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
+++ b/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
@@ -24,5 +24,5 @@ import TISwiftUtils
import Foundation
public protocol AlertPresentable {
- func present(on context: PresentationContext, completion: VoidClosure?)
+ func present(on context: AlertPresentationContext, completion: VoidClosure?)
}
diff --git a/TIUIElements/Sources/Alerts/Protocols/PresentationContext.swift b/TIUIElements/Sources/Alerts/Protocols/AlertPresentationContext.swift
similarity index 91%
rename from TIUIElements/Sources/Alerts/Protocols/PresentationContext.swift
rename to TIUIElements/Sources/Alerts/Protocols/AlertPresentationContext.swift
index caf5028b..c060a1ef 100644
--- a/TIUIElements/Sources/Alerts/Protocols/PresentationContext.swift
+++ b/TIUIElements/Sources/Alerts/Protocols/AlertPresentationContext.swift
@@ -20,8 +20,9 @@
// THE SOFTWARE.
//
+import TISwiftUtils
import UIKit
-public protocol PresentationContext {
- func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?)
+public protocol AlertPresentationContext {
+ func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: VoidClosure?)
}
diff --git a/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift b/TIUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
similarity index 70%
rename from TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift
rename to TIUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
index 7c998fc0..da9cd8e6 100644
--- a/TIUIElements/Sources/Alerts/Protocols/SwiftUIContext.swift
+++ b/TIUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
@@ -20,24 +20,17 @@
// THE SOFTWARE.
//
+import TISwiftUtils
import SwiftUI
@available(iOS 13, *)
-public protocol SwiftUIContext: PresentationContext {
- var presentedViewController: UIViewController? { get }
+public protocol SwiftUIAlertContext: AlertPresentationContext {
+ var presentingViewController: UIViewController { get set }
}
@available(iOS 13, *)
-public extension SwiftUIContext {
- var presentedViewController: UIViewController? {
- UIApplication.shared.windows.first?.rootViewController?.presentedViewController
- }
-
- func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?) {
- guard let viewController = presentedViewController else {
- return
- }
-
- viewController.present(viewControllerToPresent, animated: flag, completion: completion)
+public extension SwiftUIAlertContext {
+ func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: VoidClosure?) {
+ presentingViewController.present(viewControllerToPresent, animated: flag, completion: completion)
}
}
diff --git a/TIUIElements/Sources/Alerts/Protocols/UIKitContext.swift b/TIUIElements/Sources/Alerts/Protocols/UIKitAlertContext.swift
similarity index 94%
rename from TIUIElements/Sources/Alerts/Protocols/UIKitContext.swift
rename to TIUIElements/Sources/Alerts/Protocols/UIKitAlertContext.swift
index 5958824a..3551febb 100644
--- a/TIUIElements/Sources/Alerts/Protocols/UIKitContext.swift
+++ b/TIUIElements/Sources/Alerts/Protocols/UIKitAlertContext.swift
@@ -22,4 +22,4 @@
import UIKit
-public protocol UIKitContext: PresentationContext { }
+public protocol UIKitAlertContext: AlertPresentationContext { }
diff --git a/TIUIElements/TIUIElements.podspec b/TIUIElements/TIUIElements.podspec
index 93d0709f..620f2c14 100644
--- a/TIUIElements/TIUIElements.podspec
+++ b/TIUIElements/TIUIElements.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIUIElements'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Bunch of useful protocols and views.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIUIKitCore/TIUIKitCore.podspec b/TIUIKitCore/TIUIKitCore.podspec
index 32675f8d..93baeac2 100644
--- a/TIUIKitCore/TIUIKitCore.podspec
+++ b/TIUIKitCore/TIUIKitCore.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIUIKitCore'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Core UI elements: protocols, views and helpers.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
diff --git a/TIYandexMapUtils/TIYandexMapUtils.podspec b/TIYandexMapUtils/TIYandexMapUtils.podspec
index 851f7167..943e1a6d 100644
--- a/TIYandexMapUtils/TIYandexMapUtils.podspec
+++ b/TIYandexMapUtils/TIYandexMapUtils.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIYandexMapUtils'
- s.version = '1.22.0'
+ s.version = '1.24.0'
s.summary = 'Set of helpers for map objects clustering and interacting using Yandex Maps SDK.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }
From 81382911530255675a3af7cd12858f6c7e37ecea Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Tue, 26 Jul 2022 13:40:56 +0300
Subject: [PATCH 08/17] feat: SUI alerts added to different library
---
Package.swift | 2 ++
TISwiftUIElements/README.md | 5 +++++
.../Sources/Alerts/Modifiers/View+Alerts.swift | 3 ++-
.../Alerts/Protocols/SwiftUIAlertContext.swift | 5 ++---
TISwiftUIElements/TISwiftUIElements.podspec | 17 +++++++++++++++++
.../UIAlertController+AlertPresentable.swift | 2 +-
.../Alerts/Protocols/AlertPresentable.swift | 1 -
7 files changed, 29 insertions(+), 6 deletions(-)
create mode 100644 TISwiftUIElements/README.md
rename TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift => TISwiftUIElements/Sources/Alerts/Modifiers/View+Alerts.swift (98%)
rename {TIUIElements => TISwiftUIElements}/Sources/Alerts/Protocols/SwiftUIAlertContext.swift (96%)
create mode 100644 TISwiftUIElements/TISwiftUIElements.podspec
diff --git a/Package.swift b/Package.swift
index 0edf613e..20b41c98 100644
--- a/Package.swift
+++ b/Package.swift
@@ -14,6 +14,7 @@ let package = Package(
// MARK: - SwiftUI
.library(name: "TISwiftUICore", targets: ["TISwiftUICore"]),
+ .library(name: "TISwiftUIElements", targets: ["TISwiftUIElements"]),
// MARK: - Utils
.library(name: "TISwiftUtils", targets: ["TISwiftUtils"]),
@@ -55,6 +56,7 @@ let package = Package(
// MARK: - SwiftUI
.target(name: "TISwiftUICore", path: "TISwiftUICore/Sources"),
+ .target(name: "TISwiftUIElements", path: "TISwiftUIElements/Sources"),
// MARK: - Utils
.target(name: "TISwiftUtils", path: "TISwiftUtils/Sources"),
diff --git a/TISwiftUIElements/README.md b/TISwiftUIElements/README.md
new file mode 100644
index 00000000..6c804ac6
--- /dev/null
+++ b/TISwiftUIElements/README.md
@@ -0,0 +1,5 @@
+# TISwiftUIElements
+
+# Installation via SPM
+
+You can install this framework as a target of LeadKit.
diff --git a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift b/TISwiftUIElements/Sources/Alerts/Modifiers/View+Alerts.swift
similarity index 98%
rename from TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
rename to TISwiftUIElements/Sources/Alerts/Modifiers/View+Alerts.swift
index 2f9bea2d..1b3b4121 100644
--- a/TIUIElements/Sources/Alerts/Helpers/View+Helpers.swift
+++ b/TISwiftUIElements/Sources/Alerts/Modifiers/View+Alerts.swift
@@ -21,9 +21,10 @@
//
import TISwiftUtils
+import TIUIElements
import SwiftUI
-@available(iOS 13.0, *)
+@available(iOS 13, *)
public extension View {
/// Presents an alert with a description on a context when a given condition is true.
diff --git a/TIUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift b/TISwiftUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
similarity index 96%
rename from TIUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
rename to TISwiftUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
index da9cd8e6..0ea6ad63 100644
--- a/TIUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
+++ b/TISwiftUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
@@ -21,14 +21,13 @@
//
import TISwiftUtils
-import SwiftUI
+import TIUIElements
+import UIKit
-@available(iOS 13, *)
public protocol SwiftUIAlertContext: AlertPresentationContext {
var presentingViewController: UIViewController { get set }
}
-@available(iOS 13, *)
public extension SwiftUIAlertContext {
func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: VoidClosure?) {
presentingViewController.present(viewControllerToPresent, animated: flag, completion: completion)
diff --git a/TISwiftUIElements/TISwiftUIElements.podspec b/TISwiftUIElements/TISwiftUIElements.podspec
new file mode 100644
index 00000000..c99bcd30
--- /dev/null
+++ b/TISwiftUIElements/TISwiftUIElements.podspec
@@ -0,0 +1,17 @@
+Pod::Spec.new do |s|
+ s.name = 'TISwiftUIElements'
+ s.version = '1.24.0'
+ s.summary = 'Bunch of useful protocols and views.'
+ s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
+ s.license = { :type => 'MIT', :file => 'LICENSE' }
+ s.author = { 'petropavel13' => 'ivan.smolin@touchin.ru' }
+ s.source = { :git => 'https://github.com/TouchInstinct/LeadKit.git', :tag => s.version.to_s }
+
+ s.ios.deployment_target = '13.0'
+ s.swift_versions = ['5.3']
+
+ s.source_files = s.name + '/Sources/**/*'
+
+ s.dependency 'TIUIElements', s.version.to_s
+ s.dependency 'TISwiftUtils', s.version.to_s
+end
diff --git a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
index a2a5458a..d40ca0ef 100644
--- a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
+++ b/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
@@ -20,7 +20,7 @@
// THE SOFTWARE.
//
-import typealias TISwiftUtils.VoidClosure
+import TISwiftUtils
import UIKit
public extension UIAlertController {
diff --git a/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift b/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
index 142f5b89..64eda4e1 100644
--- a/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
+++ b/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
@@ -21,7 +21,6 @@
//
import TISwiftUtils
-import Foundation
public protocol AlertPresentable {
func present(on context: AlertPresentationContext, completion: VoidClosure?)
From ffa66048b0471db355dc69d6e79c6173564ff474 Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Tue, 26 Jul 2022 13:53:25 +0300
Subject: [PATCH 09/17] fix: removed TISwiftUIElements lib and moved components
to TISwiftUICore
---
Package.swift | 2 --
.../Sources/Alerts/Modifiers/View+Alerts.swift | 0
.../Alerts/Protocols/SwiftUIAlertContext.swift | 0
TISwiftUICore/TISwiftUICore.podspec | 2 ++
TISwiftUIElements/README.md | 5 -----
TISwiftUIElements/TISwiftUIElements.podspec | 17 -----------------
6 files changed, 2 insertions(+), 24 deletions(-)
rename {TISwiftUIElements => TISwiftUICore}/Sources/Alerts/Modifiers/View+Alerts.swift (100%)
rename {TISwiftUIElements => TISwiftUICore}/Sources/Alerts/Protocols/SwiftUIAlertContext.swift (100%)
delete mode 100644 TISwiftUIElements/README.md
delete mode 100644 TISwiftUIElements/TISwiftUIElements.podspec
diff --git a/Package.swift b/Package.swift
index 20b41c98..0edf613e 100644
--- a/Package.swift
+++ b/Package.swift
@@ -14,7 +14,6 @@ let package = Package(
// MARK: - SwiftUI
.library(name: "TISwiftUICore", targets: ["TISwiftUICore"]),
- .library(name: "TISwiftUIElements", targets: ["TISwiftUIElements"]),
// MARK: - Utils
.library(name: "TISwiftUtils", targets: ["TISwiftUtils"]),
@@ -56,7 +55,6 @@ let package = Package(
// MARK: - SwiftUI
.target(name: "TISwiftUICore", path: "TISwiftUICore/Sources"),
- .target(name: "TISwiftUIElements", path: "TISwiftUIElements/Sources"),
// MARK: - Utils
.target(name: "TISwiftUtils", path: "TISwiftUtils/Sources"),
diff --git a/TISwiftUIElements/Sources/Alerts/Modifiers/View+Alerts.swift b/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
similarity index 100%
rename from TISwiftUIElements/Sources/Alerts/Modifiers/View+Alerts.swift
rename to TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
diff --git a/TISwiftUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift b/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
similarity index 100%
rename from TISwiftUIElements/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
rename to TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
diff --git a/TISwiftUICore/TISwiftUICore.podspec b/TISwiftUICore/TISwiftUICore.podspec
index fd2b61a2..a844e1cc 100644
--- a/TISwiftUICore/TISwiftUICore.podspec
+++ b/TISwiftUICore/TISwiftUICore.podspec
@@ -12,4 +12,6 @@ Pod::Spec.new do |s|
s.source_files = s.name + '/Sources/**/*'
+ s.dependency 'TIUIElements', s.version.to_s
+ s.dependency 'TISwiftUtils', s.version.to_s
end
diff --git a/TISwiftUIElements/README.md b/TISwiftUIElements/README.md
deleted file mode 100644
index 6c804ac6..00000000
--- a/TISwiftUIElements/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# TISwiftUIElements
-
-# Installation via SPM
-
-You can install this framework as a target of LeadKit.
diff --git a/TISwiftUIElements/TISwiftUIElements.podspec b/TISwiftUIElements/TISwiftUIElements.podspec
deleted file mode 100644
index c99bcd30..00000000
--- a/TISwiftUIElements/TISwiftUIElements.podspec
+++ /dev/null
@@ -1,17 +0,0 @@
-Pod::Spec.new do |s|
- s.name = 'TISwiftUIElements'
- s.version = '1.24.0'
- s.summary = 'Bunch of useful protocols and views.'
- s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
- s.license = { :type => 'MIT', :file => 'LICENSE' }
- s.author = { 'petropavel13' => 'ivan.smolin@touchin.ru' }
- s.source = { :git => 'https://github.com/TouchInstinct/LeadKit.git', :tag => s.version.to_s }
-
- s.ios.deployment_target = '13.0'
- s.swift_versions = ['5.3']
-
- s.source_files = s.name + '/Sources/**/*'
-
- s.dependency 'TIUIElements', s.version.to_s
- s.dependency 'TISwiftUtils', s.version.to_s
-end
From 34c7407ecb8383096d4a1b6beef49029014de700 Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Tue, 26 Jul 2022 13:59:25 +0300
Subject: [PATCH 10/17] docs: SUI alerts
---
TISwiftUICore/README.md | 20 +++++++++++++++++++-
TIUIElements/README.md | 14 +-------------
2 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/TISwiftUICore/README.md b/TISwiftUICore/README.md
index 75092272..c06adcf8 100644
--- a/TISwiftUICore/README.md
+++ b/TISwiftUICore/README.md
@@ -1,3 +1,21 @@
# TISwiftUICore
-Core UI elements: protocols, views and helpers.
\ No newline at end of file
+Core UI elements: protocols, views and helpers.
+
+## SwiftUI alerts
+> SwiftUI views should conform to protocol `SwiftUIAlertContext` to present alert
+
+```swift
+var body: some View {
+ Button("Show custom alert with binding property") {
+ alertDescription = factory.okAlert(title: "Title", message: "Message")
+ isPresentedCustomAlert = true
+ }
+ }
+ .alert(isPresented: $isPresentedAlert, on: self, alert: alertDescription)
+}
+```
+
+# Installation via SPM
+
+You can install this framework as a target of LeadKit.
\ No newline at end of file
diff --git a/TIUIElements/README.md b/TIUIElements/README.md
index 9eea58ad..923d26f4 100644
--- a/TIUIElements/README.md
+++ b/TIUIElements/README.md
@@ -132,7 +132,7 @@ Use to present alerts in a few lines of code. Can be used for UIKit and SwiftUI
> You can initialize `AlertsFactory` with your own *LocalizationProvider* or use `DefaultAlertLocalizationProvider`
## Your view or view controller must implement PresentationContext protocol
-There are `UIKitAlertContext` and `SwiftUIAlertContext` protocols that are designed to make it easier to work with `AlertPresentationContext` protocol. By default, no changes need to be made for UIKit view controllers to make them conform to `UIKitAlertContext`.
+There are `UIKitAlertContext` protocol that are designed to make it easier to work with `AlertPresentationContext` protocol. By default, no changes need to be made for UIKit view controllers to make them conform to `UIKitAlertContext`.
## Custom alerts
```swift
@@ -189,18 +189,6 @@ func presentDialogueAlert() {
}
```
-## SwiftUI alerts
-```swift
-var body: some View {
- Button("Show custom alert with binding property") {
- alertDescription = factory.okAlert(title: "Title", message: "Message")
- isPresentedCustomAlert = true
- }
- }
- .alert(isPresented: $isPresentedAlert, on: self, alert: alertDescription)
-}
-```
-
# Installation via SPM
You can install this framework as a target of LeadKit.
From a88a85fe750976b2ee0252943ffccb974b05cc27 Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Tue, 26 Jul 2022 15:09:42 +0300
Subject: [PATCH 11/17] fix: move alerts into TIUIKitCore
---
TIUIElements/README.md | 62 -------------
TIUIKitCore/README.md | 88 +++++++++++++++++--
.../Alerts/Factories/AlertFactory.swift | 0
.../Sources/Alerts/Models/AlertAction.swift | 0
.../Alerts/Models/AlertDescriptor.swift | 0
.../Alerts/Protocols/AlertPresentable.swift | 0
.../Protocols/AlertPresentationContext.swift | 0
.../Alerts/Protocols/UIKitAlertContext.swift | 0
.../Alerts}/AlertDescriptor+Helpers.swift | 0
.../UIAlertController+AlertPresentable.swift | 0
.../AlertLocalizationProvider.swift | 0
.../DefaultAlertLocalizationProvider.swift | 0
TIUIKitCore/TIUIKitCore.podspec | 2 +
13 files changed, 84 insertions(+), 68 deletions(-)
rename {TIUIElements => TIUIKitCore}/Sources/Alerts/Factories/AlertFactory.swift (100%)
rename {TIUIElements => TIUIKitCore}/Sources/Alerts/Models/AlertAction.swift (100%)
rename {TIUIElements => TIUIKitCore}/Sources/Alerts/Models/AlertDescriptor.swift (100%)
rename {TIUIElements => TIUIKitCore}/Sources/Alerts/Protocols/AlertPresentable.swift (100%)
rename {TIUIElements => TIUIKitCore}/Sources/Alerts/Protocols/AlertPresentationContext.swift (100%)
rename {TIUIElements => TIUIKitCore}/Sources/Alerts/Protocols/UIKitAlertContext.swift (100%)
rename {TIUIElements/Sources/Alerts/Helpers => TIUIKitCore/Sources/Extensions/Alerts}/AlertDescriptor+Helpers.swift (100%)
rename {TIUIElements/Sources/Alerts/Helpers => TIUIKitCore/Sources/Extensions/Alerts}/UIAlertController+AlertPresentable.swift (100%)
rename {TIUIElements/Sources/Alerts/Protocols => TIUIKitCore/Sources/Localization/AlertsLocalization}/AlertLocalizationProvider.swift (100%)
rename {TIUIElements/Sources/Alerts/Models => TIUIKitCore/Sources/Localization/AlertsLocalization}/DefaultAlertLocalizationProvider.swift (100%)
diff --git a/TIUIElements/README.md b/TIUIElements/README.md
index 923d26f4..1814f815 100644
--- a/TIUIElements/README.md
+++ b/TIUIElements/README.md
@@ -127,68 +127,6 @@ class ViewController: UITableViewController, CollapsibleViewsContainer {
-# AlertsFactory
-Use to present alerts in a few lines of code. Can be used for UIKit and SwiftUI
-> You can initialize `AlertsFactory` with your own *LocalizationProvider* or use `DefaultAlertLocalizationProvider`
-
-## Your view or view controller must implement PresentationContext protocol
-There are `UIKitAlertContext` protocol that are designed to make it easier to work with `AlertPresentationContext` protocol. By default, no changes need to be made for UIKit view controllers to make them conform to `UIKitAlertContext`.
-
-## Custom alerts
-```swift
-// Presents alert
-func presentAlert() {
- factory
- .alert(title: "Alert's title",
- message: "Alert's message",
- tint: .systemBlue,
- actions: [
- AlertAction(title: "Ok", style: .default, action: nil),
- AlertAction(title: "Cancel", style: .cancel, action: nil)
- ])
- .present(on: self)
-}
-
-// Presents sheet alert
-func presentSheetAlert() {
- factory
- .sheetAlert(title: "Alert's title",
- message: "Alert's message",
- tint: .systemBlue,
- actions: [
- AlertAction(title: "Ok", style: .default, action: nil),
- AlertAction(title: "Cancel", style: .cancel, action: nil)
- ])
- .present(on: self)
-}
-```
-
-## Default alerts
-```swift
-// Ok alert
-func presentOkAlert() {
- factory
- .okAlert(title: "Title", message: "Message")
- .present(on: self)
-}
-
-// Retry alert
-func presentRetryAlert() {
- factory
- .retryAlert(title: "Title", message: "Message") { [weak self] in
- self?.presentOkAlert()
- }
- .present(on: self)
-}
-
-// Dialogue alert
-func presentDialogueAlert() {
- factory
- .dialogueAlert(title: "Title", message: "Message")
- .present(on: self)
-}
-```
-
# Installation via SPM
You can install this framework as a target of LeadKit.
diff --git a/TIUIKitCore/README.md b/TIUIKitCore/README.md
index 96d028a7..bbd3408d 100644
--- a/TIUIKitCore/README.md
+++ b/TIUIKitCore/README.md
@@ -4,11 +4,87 @@ Core UI elements: protocols, views and helpers.
# Protocols
-- [InitializableView](InitializableView/InitializableView.swift) - protocol with methods that should be called in constructor methods of view.
-- [Animatable](Animatable/Animatable.swift) - protocol that ensures that specific type support basic animation actions.
-- [ActivityIndicator](ActivityIndicator/ActivityIndicator.swift) - basic activity indicator.
-- [ActivityIndicatorHolder](ActivityIndicator/ActivityIndicatorHolder.swift) - placeholder view, containing activity indicator.
+- [InitializableView](Sources/InitializableView/InitializableViewProtocol.swift) - protocol with methods that should be called in constructor methods of view.
+- [Animatable](Sources/ActivityIndicator/Animatable.swift) - protocol that ensures that specific type support basic animation actions.
+- [ActivityIndicator](Sources/ActivityIndicator/ActivityIndicator.swift) - basic activity indicator.
+- [ActivityIndicatorHolder](Sources/ActivityIndicator/ActivityIndicatorHolder.swift) - placeholder view, containing activity indicator.
+- [AlertLocalizationProvider](Sources/Localization/AlertsLocalization/AlertLocalizationProvider.swift) - protocol that ensures that localization for alerts will be provided.
+- [AlertPresentable](Sources/Alerts/Protocols/AlertPresentable.swift) - protocol indicates that certain object can present alerts.
+- [AlertPresentationContext](Sources/Alerts/Protocols/AlertPresentationContext.swift) - protocol indicates that certain object can present alert on top of itself.
+- [UIKitAlertContext](Sources/Alerts/Protocols/UIKitAlertContext.swift) - helper to provide easy conformance of `UIViewController` to `AlertPresentationContext`.
-# Views
+# Models
-- [BaseInitializableView](BaseInitializableView/BaseInitializableView.swift) - UIView conformance to InitializableView.
+- [DefaultAlertLocalizationProvider](Sources/Localization/AlertsLocalization/DefaultAlertLocalizationProvider.swift) - default localization provider for alerts.
+- [AlertAction](Sources/Alerts/Models/AlertAction.swift) - representation of alert action
+- [AlertDescriptor](Sources/Alerts/Models/AlertDescriptor.swift) - struct that holds all needed information to present alert
+
+# Factories
+
+- [AlertsFactory](Sources/Alerts/Factories/AlertFactory.swift) - factory to present alerts.
+
+## AlertsFactory
+Use to present alerts in a few lines of code. Can be used for UIKit and SwiftUI
+> You can initialize `AlertsFactory` with your own *LocalizationProvider* or use `DefaultAlertLocalizationProvider`
+
+### Your view or view controller must implement PresentationContext protocol
+There are `UIKitAlertContext` protocol that are designed to make it easier to work with `AlertPresentationContext` protocol. By default, no changes need to be made for UIKit view controllers to make them conform to `UIKitAlertContext`.
+
+## Custom alerts
+```swift
+// Presents alert
+func presentAlert() {
+ factory
+ .alert(title: "Alert's title",
+ message: "Alert's message",
+ tint: .systemBlue,
+ actions: [
+ AlertAction(title: "Ok", style: .default, action: nil),
+ AlertAction(title: "Cancel", style: .cancel, action: nil)
+ ])
+ .present(on: self)
+}
+
+// Presents sheet alert
+func presentSheetAlert() {
+ factory
+ .sheetAlert(title: "Alert's title",
+ message: "Alert's message",
+ tint: .systemBlue,
+ actions: [
+ AlertAction(title: "Ok", style: .default, action: nil),
+ AlertAction(title: "Cancel", style: .cancel, action: nil)
+ ])
+ .present(on: self)
+}
+```
+
+## Default alerts
+```swift
+// Ok alert
+func presentOkAlert() {
+ factory
+ .okAlert(title: "Title", message: "Message")
+ .present(on: self)
+}
+
+// Retry alert
+func presentRetryAlert() {
+ factory
+ .retryAlert(title: "Title", message: "Message") { [weak self] in
+ self?.presentOkAlert()
+ }
+ .present(on: self)
+}
+
+// Dialogue alert
+func presentDialogueAlert() {
+ factory
+ .dialogueAlert(title: "Title", message: "Message")
+ .present(on: self)
+}
+```
+
+# Installation via SPM
+
+You can install this framework as a target of LeadKit.
diff --git a/TIUIElements/Sources/Alerts/Factories/AlertFactory.swift b/TIUIKitCore/Sources/Alerts/Factories/AlertFactory.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Factories/AlertFactory.swift
rename to TIUIKitCore/Sources/Alerts/Factories/AlertFactory.swift
diff --git a/TIUIElements/Sources/Alerts/Models/AlertAction.swift b/TIUIKitCore/Sources/Alerts/Models/AlertAction.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Models/AlertAction.swift
rename to TIUIKitCore/Sources/Alerts/Models/AlertAction.swift
diff --git a/TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift b/TIUIKitCore/Sources/Alerts/Models/AlertDescriptor.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Models/AlertDescriptor.swift
rename to TIUIKitCore/Sources/Alerts/Models/AlertDescriptor.swift
diff --git a/TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Protocols/AlertPresentable.swift
rename to TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
diff --git a/TIUIElements/Sources/Alerts/Protocols/AlertPresentationContext.swift b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Protocols/AlertPresentationContext.swift
rename to TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift
diff --git a/TIUIElements/Sources/Alerts/Protocols/UIKitAlertContext.swift b/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Protocols/UIKitAlertContext.swift
rename to TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
diff --git a/TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift b/TIUIKitCore/Sources/Extensions/Alerts/AlertDescriptor+Helpers.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Helpers/AlertDescriptor+Helpers.swift
rename to TIUIKitCore/Sources/Extensions/Alerts/AlertDescriptor+Helpers.swift
diff --git a/TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift b/TIUIKitCore/Sources/Extensions/Alerts/UIAlertController+AlertPresentable.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Helpers/UIAlertController+AlertPresentable.swift
rename to TIUIKitCore/Sources/Extensions/Alerts/UIAlertController+AlertPresentable.swift
diff --git a/TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift b/TIUIKitCore/Sources/Localization/AlertsLocalization/AlertLocalizationProvider.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Protocols/AlertLocalizationProvider.swift
rename to TIUIKitCore/Sources/Localization/AlertsLocalization/AlertLocalizationProvider.swift
diff --git a/TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift b/TIUIKitCore/Sources/Localization/AlertsLocalization/DefaultAlertLocalizationProvider.swift
similarity index 100%
rename from TIUIElements/Sources/Alerts/Models/DefaultAlertLocalizationProvider.swift
rename to TIUIKitCore/Sources/Localization/AlertsLocalization/DefaultAlertLocalizationProvider.swift
diff --git a/TIUIKitCore/TIUIKitCore.podspec b/TIUIKitCore/TIUIKitCore.podspec
index 93baeac2..2da9cae0 100644
--- a/TIUIKitCore/TIUIKitCore.podspec
+++ b/TIUIKitCore/TIUIKitCore.podspec
@@ -12,4 +12,6 @@ Pod::Spec.new do |s|
s.source_files = s.name + '/Sources/**/*'
s.framework = 'UIKit'
+
+ s.dependency 'TISwiftUtils', s.version.to_s
end
From bf46b602a389c4f979d71c97affa7b7676f8f5fd Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Tue, 26 Jul 2022 15:20:33 +0300
Subject: [PATCH 12/17] fix: code review notes
---
TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift | 2 +-
.../Sources/Alerts/Protocols/SwiftUIAlertContext.swift | 2 +-
TISwiftUICore/TISwiftUICore.podspec | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift b/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
index 1b3b4121..50c335fe 100644
--- a/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
+++ b/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
@@ -21,7 +21,7 @@
//
import TISwiftUtils
-import TIUIElements
+import TIUIKitCore
import SwiftUI
@available(iOS 13, *)
diff --git a/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift b/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
index 0ea6ad63..d490bef4 100644
--- a/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
+++ b/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
@@ -21,7 +21,7 @@
//
import TISwiftUtils
-import TIUIElements
+import TIUIKitCore
import UIKit
public protocol SwiftUIAlertContext: AlertPresentationContext {
diff --git a/TISwiftUICore/TISwiftUICore.podspec b/TISwiftUICore/TISwiftUICore.podspec
index a844e1cc..9546161c 100644
--- a/TISwiftUICore/TISwiftUICore.podspec
+++ b/TISwiftUICore/TISwiftUICore.podspec
@@ -12,6 +12,6 @@ Pod::Spec.new do |s|
s.source_files = s.name + '/Sources/**/*'
- s.dependency 'TIUIElements', s.version.to_s
+ s.dependency 'TIUIKitCore', s.version.to_s
s.dependency 'TISwiftUtils', s.version.to_s
end
From cfbf53faf8519d9937a4295307adaa121cb2407f Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Tue, 26 Jul 2022 15:33:50 +0300
Subject: [PATCH 13/17] fix: code review notes
---
.../Sources/Extensions/Alerts/AlertDescriptor+Helpers.swift | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/TIUIKitCore/Sources/Extensions/Alerts/AlertDescriptor+Helpers.swift b/TIUIKitCore/Sources/Extensions/Alerts/AlertDescriptor+Helpers.swift
index 192f504e..716d2522 100644
--- a/TIUIKitCore/Sources/Extensions/Alerts/AlertDescriptor+Helpers.swift
+++ b/TIUIKitCore/Sources/Extensions/Alerts/AlertDescriptor+Helpers.swift
@@ -34,10 +34,10 @@ public extension AlertDescriptor {
present(on: context, alertViewFactory: alertFactory, completion: completion)
}
-
+
func present(on context: AlertPresentationContext,
- alertViewFactory: Closure,
- completion: VoidClosure? = nil) {
+ alertViewFactory: Closure,
+ completion: VoidClosure? = nil) {
alertViewFactory(self).present(on: context, completion: completion)
}
}
From 9a427adab713b2d481b9907db5b4df77ff88f2b7 Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Wed, 27 Jul 2022 13:58:44 +0300
Subject: [PATCH 14/17] fix: code review notes + added custom modifier for
alerts
---
TISwiftUICore/README.md | 22 +++++---
.../Alerts/Modifiers/AlertModifier.swift | 51 +++++++++++++++++++
.../Alerts/Modifiers/View+Alerts.swift | 22 +++-----
TIUIKitCore/README.md | 28 +++++++++-
.../Alerts/Factories/AlertFactory.swift | 10 ++--
.../Sources/Alerts/Models/AlertAction.swift | 2 +-
.../Alerts/Models/AlertDescriptor.swift | 2 +-
.../Alerts/Protocols/AlertPresentable.swift | 1 +
.../Protocols/AlertPresentationContext.swift | 1 +
.../Alerts/Protocols/UIKitAlertContext.swift | 2 -
.../DefaultAlertLocalizationProvider.swift | 2 +-
11 files changed, 111 insertions(+), 32 deletions(-)
create mode 100644 TISwiftUICore/Sources/Alerts/Modifiers/AlertModifier.swift
diff --git a/TISwiftUICore/README.md b/TISwiftUICore/README.md
index c06adcf8..95ebf38e 100644
--- a/TISwiftUICore/README.md
+++ b/TISwiftUICore/README.md
@@ -3,16 +3,26 @@
Core UI elements: protocols, views and helpers.
## SwiftUI alerts
-> SwiftUI views should conform to protocol `SwiftUIAlertContext` to present alert
+> SwiftUI views should conform to protocol `SwiftUIAlertContext` to present alerts. This means that the view must implement the presentingViewController property. This controller is a context from which the alert will be shown.
```swift
-var body: some View {
- Button("Show custom alert with binding property") {
- alertDescription = factory.okAlert(title: "Title", message: "Message")
- isPresentedCustomAlert = true
+struct ContentView: View, SwiftUIAlertContext {
+
+ private let factory = AlertFactory()
+
+ @State private var alertDescription: AlertDescriptor
+ @State private var isAlertPresented = false
+
+ var presentingViewController: UIViewController
+
+ var body: some View {
+ Button("Show custom alert with binding property") {
+ alertDescription = factory.okAlert(title: "Title", message: "Message")
+ isAlertPresented = true
+ }
}
+ .alert(isPresented: $isAlertPresented, on: self, alert: alertDescription)
}
- .alert(isPresented: $isPresentedAlert, on: self, alert: alertDescription)
}
```
diff --git a/TISwiftUICore/Sources/Alerts/Modifiers/AlertModifier.swift b/TISwiftUICore/Sources/Alerts/Modifiers/AlertModifier.swift
new file mode 100644
index 00000000..c406ae15
--- /dev/null
+++ b/TISwiftUICore/Sources/Alerts/Modifiers/AlertModifier.swift
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2022 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 SwiftUI
+import TISwiftUtils
+import TIUIKitCore
+
+@available(iOS 13, *)
+struct AlertModifier: ViewModifier {
+
+ @Binding var isPresented: Bool
+
+ let context: AlertPresentationContext
+ let alertDescriptor: AlertDescriptor
+ let alertPresentable: AlertPresentable?
+
+ func body(content: Content) -> some View {
+ if isPresented {
+ let completion: VoidClosure = {
+ isPresented = false
+ }
+
+ if let alertPresentable = alertPresentable {
+ alertPresentable.present(on: context, completion: completion)
+ } else {
+ alertDescriptor.present(on: context, completion: completion)
+ }
+ }
+
+ return content
+ }
+}
diff --git a/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift b/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
index 50c335fe..ed5cf6f2 100644
--- a/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
+++ b/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
@@ -36,13 +36,10 @@ public extension View {
on context: AlertPresentationContext,
alert: AlertDescriptor) -> some View {
- if isPresented.wrappedValue {
- alert.present(on: context) {
- isPresented.wrappedValue = false
- }
- }
-
- return self
+ modifier(AlertModifier(isPresented: isPresented,
+ context: context,
+ alertDescriptor: alert,
+ alertPresentable: nil))
}
/// Presents an alert with a description on a context with custom configuration of the alert when a given condition is true.
@@ -56,12 +53,9 @@ public extension View {
alertDescriptor descriptor: AlertDescriptor,
alertViewFactory: Closure) -> some View {
- if isPresented.wrappedValue {
- alertViewFactory(descriptor).present(on: context) {
- isPresented.wrappedValue = false
- }
- }
-
- return self
+ modifier(AlertModifier(isPresented: isPresented,
+ context: context,
+ alertDescriptor: descriptor,
+ alertPresentable: alertViewFactory(descriptor)))
}
}
diff --git a/TIUIKitCore/README.md b/TIUIKitCore/README.md
index bbd3408d..22f9601d 100644
--- a/TIUIKitCore/README.md
+++ b/TIUIKitCore/README.md
@@ -27,8 +27,32 @@ Core UI elements: protocols, views and helpers.
Use to present alerts in a few lines of code. Can be used for UIKit and SwiftUI
> You can initialize `AlertsFactory` with your own *LocalizationProvider* or use `DefaultAlertLocalizationProvider`
-### Your view or view controller must implement PresentationContext protocol
-There are `UIKitAlertContext` protocol that are designed to make it easier to work with `AlertPresentationContext` protocol. By default, no changes need to be made for UIKit view controllers to make them conform to `UIKitAlertContext`.
+### Your view or view controller must implement AlertPresentationContext protocol
+The implementation of the protocol says that an alert can be shown from this object. Also there is a `UIKitAlertContext` protocol designed to make it easier to work with `AlertPresentationContext` protocol. By default, no changes need to be made for UIKit view controllers to make them conform to `UIKitAlertContext`.
+
+### Your alert controller must implement AlertPresentable protocol
+The implementation of this protocol says that an alert can be shown from the context. By default, the standard `UIAlertController` conforms to the protocol. Accordingly, when using a custom alert, it must also conform to the protocol:
+
+```swift
+import PopupDialog
+
+extension PopupDialog: AlertPresentable {
+ @discardableResult
+ public func configured(with configuration: AlertDescriptor) -> Self {
+ title = configuration.title
+
+ for action in configuration.actions {
+ addButton(DefaultButton(title: action.title, action: action.action))
+ }
+
+ return self
+ }
+
+ public func present(on context: AlertPresentationContext, completion: VoidClosure?) {
+ context.present(self, animated: true, completion: completion)
+ }
+}
+```
## Custom alerts
```swift
diff --git a/TIUIKitCore/Sources/Alerts/Factories/AlertFactory.swift b/TIUIKitCore/Sources/Alerts/Factories/AlertFactory.swift
index 9a50f530..9376a8ea 100644
--- a/TIUIKitCore/Sources/Alerts/Factories/AlertFactory.swift
+++ b/TIUIKitCore/Sources/Alerts/Factories/AlertFactory.swift
@@ -36,7 +36,7 @@ open class AlertFactory {
/// - message: A text string used as the message of the alert.
/// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue.
/// - actions: An array of actions of the alert.
- /// - Returns: Alert descriptor, which can be used to present alert view.
+ /// - Returns: Alert descriptor which can be used to present alert view.
open func alert(title: String? = nil,
message: String? = nil,
tint: UIColor = .systemBlue,
@@ -54,7 +54,7 @@ open class AlertFactory {
/// - message: A text string used as the message of the sheet alert.
/// - tint: A color used as a tint color of the sheet alert. Default color is UIColor.systemBlue.
/// - actions: An array of actions of the sheet alert.
- /// - Returns: Alert descriptor, which can be used to present sheet alert view.
+ /// - Returns: Alert descriptor which can be used to present sheet alert view.
open func sheetAlert(title: String? = nil,
message: String? = nil,
tint: UIColor = .systemBlue,
@@ -72,7 +72,7 @@ open class AlertFactory {
/// - title: A text string used as the title of the alert.
/// - message: A text string used as the message of the alert.
/// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue.
- /// - Returns: Alert descriptor, which can be used to present alert view.
+ /// - Returns: Alert descriptor which can be used to present alert view.
open func okAlert(title: String? = nil,
message: String? = nil,
tint: UIColor = .systemBlue) -> AlertDescriptor {
@@ -89,7 +89,7 @@ open class AlertFactory {
/// - message: A text string used as the message of the alert.
/// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue.
/// - retryAction: A closure called by tapping on the retry button of the alert.
- /// - Returns: Alert descriptor, which can be used to present alert view.
+ /// - Returns: Alert descriptor which can be used to present alert view.
open func retryAlert(title: String? = nil,
message: String? = nil,
tint: UIColor = .systemBlue,
@@ -111,7 +111,7 @@ open class AlertFactory {
/// - tint: A color used as a tint color of the alert. Default color is UIColor.systemBlue.
/// - yesAction: A closure called by tapping on the yes button of the alert.
/// - noAction: A closure called by tapping on the no button of the alert.
- /// - Returns: Alert descriptor, which can be used to present alert view.
+ /// - Returns: Alert descriptor which can be used to present alert view.
open func dialogueAlert(title: String? = nil,
message: String? = nil,
tint: UIColor = .systemBlue,
diff --git a/TIUIKitCore/Sources/Alerts/Models/AlertAction.swift b/TIUIKitCore/Sources/Alerts/Models/AlertAction.swift
index c90b8996..d919c7ee 100644
--- a/TIUIKitCore/Sources/Alerts/Models/AlertAction.swift
+++ b/TIUIKitCore/Sources/Alerts/Models/AlertAction.swift
@@ -23,7 +23,7 @@
import TISwiftUtils
import UIKit
-// struct describe alert button information
+/// A struct describes an alert button information
public struct AlertAction {
public let id = UUID()
diff --git a/TIUIKitCore/Sources/Alerts/Models/AlertDescriptor.swift b/TIUIKitCore/Sources/Alerts/Models/AlertDescriptor.swift
index 2efb8190..2c6c81b8 100644
--- a/TIUIKitCore/Sources/Alerts/Models/AlertDescriptor.swift
+++ b/TIUIKitCore/Sources/Alerts/Models/AlertDescriptor.swift
@@ -22,7 +22,7 @@
import UIKit
-/// Struct describes alert data
+/// A struct describes alert data
public struct AlertDescriptor {
/// Alert title
diff --git a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
index 64eda4e1..163177a5 100644
--- a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
+++ b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
@@ -22,6 +22,7 @@
import TISwiftUtils
+/// A protocol represents an alert which can be presented on the given context
public protocol AlertPresentable {
func present(on context: AlertPresentationContext, completion: VoidClosure?)
}
diff --git a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift
index c060a1ef..72dd720d 100644
--- a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift
+++ b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift
@@ -23,6 +23,7 @@
import TISwiftUtils
import UIKit
+/// A context from where the alert can be presented
public protocol AlertPresentationContext {
func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: VoidClosure?)
}
diff --git a/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift b/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
index 3551febb..3652242b 100644
--- a/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
+++ b/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
@@ -20,6 +20,4 @@
// THE SOFTWARE.
//
-import UIKit
-
public protocol UIKitAlertContext: AlertPresentationContext { }
diff --git a/TIUIKitCore/Sources/Localization/AlertsLocalization/DefaultAlertLocalizationProvider.swift b/TIUIKitCore/Sources/Localization/AlertsLocalization/DefaultAlertLocalizationProvider.swift
index 9b506998..b3c0e95d 100644
--- a/TIUIKitCore/Sources/Localization/AlertsLocalization/DefaultAlertLocalizationProvider.swift
+++ b/TIUIKitCore/Sources/Localization/AlertsLocalization/DefaultAlertLocalizationProvider.swift
@@ -22,7 +22,7 @@
import Foundation
-/// Provide default localization for alerts' buttons
+/// Provides default localization for alerts' buttons
open class DefaultAlertLocalizationProvider: AlertLocalizationProvider {
public var bundle: Bundle
From 174d472f1bd55d84c37af2e0dcdb412a9b096b0b Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Wed, 27 Jul 2022 14:40:38 +0300
Subject: [PATCH 15/17] revert: deleted alert modifier
---
.../Alerts/Modifiers/AlertModifier.swift | 51 -------------------
.../Alerts/Modifiers/View+Alerts.swift | 22 +++++---
2 files changed, 14 insertions(+), 59 deletions(-)
delete mode 100644 TISwiftUICore/Sources/Alerts/Modifiers/AlertModifier.swift
diff --git a/TISwiftUICore/Sources/Alerts/Modifiers/AlertModifier.swift b/TISwiftUICore/Sources/Alerts/Modifiers/AlertModifier.swift
deleted file mode 100644
index c406ae15..00000000
--- a/TISwiftUICore/Sources/Alerts/Modifiers/AlertModifier.swift
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Copyright (c) 2022 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 SwiftUI
-import TISwiftUtils
-import TIUIKitCore
-
-@available(iOS 13, *)
-struct AlertModifier: ViewModifier {
-
- @Binding var isPresented: Bool
-
- let context: AlertPresentationContext
- let alertDescriptor: AlertDescriptor
- let alertPresentable: AlertPresentable?
-
- func body(content: Content) -> some View {
- if isPresented {
- let completion: VoidClosure = {
- isPresented = false
- }
-
- if let alertPresentable = alertPresentable {
- alertPresentable.present(on: context, completion: completion)
- } else {
- alertDescriptor.present(on: context, completion: completion)
- }
- }
-
- return content
- }
-}
diff --git a/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift b/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
index ed5cf6f2..50c335fe 100644
--- a/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
+++ b/TISwiftUICore/Sources/Alerts/Modifiers/View+Alerts.swift
@@ -36,10 +36,13 @@ public extension View {
on context: AlertPresentationContext,
alert: AlertDescriptor) -> some View {
- modifier(AlertModifier(isPresented: isPresented,
- context: context,
- alertDescriptor: alert,
- alertPresentable: nil))
+ if isPresented.wrappedValue {
+ alert.present(on: context) {
+ isPresented.wrappedValue = false
+ }
+ }
+
+ return self
}
/// Presents an alert with a description on a context with custom configuration of the alert when a given condition is true.
@@ -53,9 +56,12 @@ public extension View {
alertDescriptor descriptor: AlertDescriptor,
alertViewFactory: Closure) -> some View {
- modifier(AlertModifier(isPresented: isPresented,
- context: context,
- alertDescriptor: descriptor,
- alertPresentable: alertViewFactory(descriptor)))
+ if isPresented.wrappedValue {
+ alertViewFactory(descriptor).present(on: context) {
+ isPresented.wrappedValue = false
+ }
+ }
+
+ return self
}
}
From a917723dcb7faf2f7f52808a0dfb674694b63139 Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Wed, 27 Jul 2022 16:08:13 +0300
Subject: [PATCH 16/17] docs: code review notes
---
.../Protocols/SwiftUIAlertContext.swift | 13 ++++++++++
.../Alerts/Protocols/AlertPresentable.swift | 24 ++++++++++++++++++-
.../Protocols/AlertPresentationContext.swift | 2 +-
.../Alerts/Protocols/UIKitAlertContext.swift | 8 +++++++
.../AlertLocalizationProvider.swift | 1 +
5 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift b/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
index d490bef4..b9585f52 100644
--- a/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
+++ b/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
@@ -24,7 +24,20 @@ import TISwiftUtils
import TIUIKitCore
import UIKit
+/// A SwiftUI context from where the alert can be presented.
+///
+/// ```
+/// // View that can present alerts.
+/// struct ContentView: View, SwiftUIAlerContext {
+/// var presentingViewController: UIViewController
+///
+/// var body: some View {
+/// // View realization.
+/// }
+/// }
+/// ```
public protocol SwiftUIAlertContext: AlertPresentationContext {
+ /// A view controller that represents a context from which the alert will be shown.
var presentingViewController: UIViewController { get set }
}
diff --git a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
index 163177a5..e042b953 100644
--- a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
+++ b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
@@ -22,7 +22,29 @@
import TISwiftUtils
-/// A protocol represents an alert which can be presented on the given context
+/// A protocol represents an alert which can be presented on the given context.
+///
+/// ```import PopupDialog
+///
+/// extension PopupDialog: AlertPresentable {
+/// @discardableResult
+/// public func configured(with configuration: AlertDescriptor) -> Self {
+/// title = configuration.title
+///
+/// for action in configuration.actions {
+/// addButton(DefaultButton(title: action.title, action: action.action))
+/// }
+///
+/// return self
+/// }
+///
+/// public func present(on context: AlertPresentationContext, completion: VoidClosure?) {
+/// context.present(self, animated: true, completion: completion)
+/// }
+/// }
+/// ```
+///
+/// The implementation of this protocol says that an alert can be shown from the context. By default, the standard `UIAlertController` conforms to the protocol. Accordingly, when using a custom alert, it must also conform to the protocol.
public protocol AlertPresentable {
func present(on context: AlertPresentationContext, completion: VoidClosure?)
}
diff --git a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift
index 72dd720d..377a4086 100644
--- a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift
+++ b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentationContext.swift
@@ -23,7 +23,7 @@
import TISwiftUtils
import UIKit
-/// A context from where the alert can be presented
+/// A context from where the alert can be presented.
public protocol AlertPresentationContext {
func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: VoidClosure?)
}
diff --git a/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift b/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
index 3652242b..342f9a32 100644
--- a/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
+++ b/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
@@ -20,4 +20,12 @@
// THE SOFTWARE.
//
+/// An UIKit context from where the alert can be presented.
+///
+/// ```
+/// // View controller that can present alerts.
+/// class ViewController: UIViewController, UIKitAlerContext {
+/// // Realization of the view controller
+/// }
+/// ```
public protocol UIKitAlertContext: AlertPresentationContext { }
diff --git a/TIUIKitCore/Sources/Localization/AlertsLocalization/AlertLocalizationProvider.swift b/TIUIKitCore/Sources/Localization/AlertsLocalization/AlertLocalizationProvider.swift
index 98795b27..85fb451a 100644
--- a/TIUIKitCore/Sources/Localization/AlertsLocalization/AlertLocalizationProvider.swift
+++ b/TIUIKitCore/Sources/Localization/AlertsLocalization/AlertLocalizationProvider.swift
@@ -20,6 +20,7 @@
// THE SOFTWARE.
//
+/// A provider of localization for common buttons' titles of the alerts.
public protocol AlertLocalizationProvider {
var okTitle: String { get }
var cancelTitle: String { get }
From 17a70d613b100c7a61b0b3ec6c783584b649f82e Mon Sep 17 00:00:00 2001
From: Nikita Semenov
Date: Wed, 27 Jul 2022 17:37:34 +0300
Subject: [PATCH 17/17] docs: code review notes
---
TISwiftUICore/README.md | 17 +++++++++++++-
.../Protocols/SwiftUIAlertContext.swift | 11 ---------
TIUIKitCore/README.md | 7 ++++++
.../Alerts/Protocols/AlertPresentable.swift | 23 +------------------
.../Alerts/Protocols/UIKitAlertContext.swift | 7 ------
5 files changed, 24 insertions(+), 41 deletions(-)
diff --git a/TISwiftUICore/README.md b/TISwiftUICore/README.md
index 95ebf38e..98a9cb3a 100644
--- a/TISwiftUICore/README.md
+++ b/TISwiftUICore/README.md
@@ -3,7 +3,22 @@
Core UI elements: protocols, views and helpers.
## SwiftUI alerts
-> SwiftUI views should conform to protocol `SwiftUIAlertContext` to present alerts. This means that the view must implement the presentingViewController property. This controller is a context from which the alert will be shown.
+
+### SwiftUI views should conform to protocol `SwiftUIAlertContext` to present alerts.
+This means that the view must implement the presentingViewController property. This controller is a context from which the alert will be shown.
+
+```swift
+// View that can present alerts.
+struct ContentView: View, SwiftUIAlerContext {
+ var presentingViewController: UIViewController
+
+ var body: some View {
+ // View realization.
+ }
+}
+```
+
+## Alerts usage example
```swift
struct ContentView: View, SwiftUIAlertContext {
diff --git a/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift b/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
index b9585f52..68bad482 100644
--- a/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
+++ b/TISwiftUICore/Sources/Alerts/Protocols/SwiftUIAlertContext.swift
@@ -25,17 +25,6 @@ import TIUIKitCore
import UIKit
/// A SwiftUI context from where the alert can be presented.
-///
-/// ```
-/// // View that can present alerts.
-/// struct ContentView: View, SwiftUIAlerContext {
-/// var presentingViewController: UIViewController
-///
-/// var body: some View {
-/// // View realization.
-/// }
-/// }
-/// ```
public protocol SwiftUIAlertContext: AlertPresentationContext {
/// A view controller that represents a context from which the alert will be shown.
var presentingViewController: UIViewController { get set }
diff --git a/TIUIKitCore/README.md b/TIUIKitCore/README.md
index 22f9601d..276ef7ff 100644
--- a/TIUIKitCore/README.md
+++ b/TIUIKitCore/README.md
@@ -30,6 +30,13 @@ Use to present alerts in a few lines of code. Can be used for UIKit and SwiftUI
### Your view or view controller must implement AlertPresentationContext protocol
The implementation of the protocol says that an alert can be shown from this object. Also there is a `UIKitAlertContext` protocol designed to make it easier to work with `AlertPresentationContext` protocol. By default, no changes need to be made for UIKit view controllers to make them conform to `UIKitAlertContext`.
+```swift
+// View controller that can present alerts.
+class ViewController: UIViewController, UIKitAlerContext {
+ // Realization of the view controller
+}
+```
+
### Your alert controller must implement AlertPresentable protocol
The implementation of this protocol says that an alert can be shown from the context. By default, the standard `UIAlertController` conforms to the protocol. Accordingly, when using a custom alert, it must also conform to the protocol:
diff --git a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
index e042b953..b24d66cd 100644
--- a/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
+++ b/TIUIKitCore/Sources/Alerts/Protocols/AlertPresentable.swift
@@ -23,28 +23,7 @@
import TISwiftUtils
/// A protocol represents an alert which can be presented on the given context.
-///
-/// ```import PopupDialog
-///
-/// extension PopupDialog: AlertPresentable {
-/// @discardableResult
-/// public func configured(with configuration: AlertDescriptor) -> Self {
-/// title = configuration.title
-///
-/// for action in configuration.actions {
-/// addButton(DefaultButton(title: action.title, action: action.action))
-/// }
-///
-/// return self
-/// }
-///
-/// public func present(on context: AlertPresentationContext, completion: VoidClosure?) {
-/// context.present(self, animated: true, completion: completion)
-/// }
-/// }
-/// ```
-///
-/// The implementation of this protocol says that an alert can be shown from the context. By default, the standard `UIAlertController` conforms to the protocol. Accordingly, when using a custom alert, it must also conform to the protocol.
+/// The implementation of this protocol says that an alert can be shown from the context. By default, the standard `UIAlertController` conforms to the protocol.
public protocol AlertPresentable {
func present(on context: AlertPresentationContext, completion: VoidClosure?)
}
diff --git a/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift b/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
index 342f9a32..7fdcf8e1 100644
--- a/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
+++ b/TIUIKitCore/Sources/Alerts/Protocols/UIKitAlertContext.swift
@@ -21,11 +21,4 @@
//
/// An UIKit context from where the alert can be presented.
-///
-/// ```
-/// // View controller that can present alerts.
-/// class ViewController: UIViewController, UIKitAlerContext {
-/// // Realization of the view controller
-/// }
-/// ```
public protocol UIKitAlertContext: AlertPresentationContext { }