From 3a6fb3f4c2369441f17b340070b7409abe99d021 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Thu, 3 Jun 2021 10:58:48 -0500
Subject: [PATCH 01/38] Update changelog
---
CHANGELOG.md | 6 ++++++
iMessageDemo/Podfile.lock | 2 +-
iMessageDemo/Pods/Manifest.lock | 2 +-
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 08f50bb..f10c7f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 9.0.3
+
+### Fixes
+
+* #465 - Fix broken Carthage build. The Carthage build was broken due to the `iMessageDemo` project's use of CocoaPods and the automatically generated `SwiftMessages` framework scheme created by CocoaPods. The podfile was modified to delete this scheme, but Carthage users may need to run `pod install` on the `iMessagesDemo` project, if they have CocoaPods installed, or manually delete the `iMessageDemo/Pods/Pods.xcodeproj/xcuserdata` folder.
+
## 9.0.2
### Fixes
diff --git a/iMessageDemo/Podfile.lock b/iMessageDemo/Podfile.lock
index b7d82fb..54bd951 100644
--- a/iMessageDemo/Podfile.lock
+++ b/iMessageDemo/Podfile.lock
@@ -11,6 +11,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
SwiftMessages: 077f19126c24033fe24042237ecc20261adb46e4
-PODFILE CHECKSUM: dde250cdcd60ccf6ec0a51da5a633d36b9f83a3b
+PODFILE CHECKSUM: 2eb9a33592d0c52131c37a9dd169a8c4604ffd7b
COCOAPODS: 1.10.0
diff --git a/iMessageDemo/Pods/Manifest.lock b/iMessageDemo/Pods/Manifest.lock
index b7d82fb..54bd951 100644
--- a/iMessageDemo/Pods/Manifest.lock
+++ b/iMessageDemo/Pods/Manifest.lock
@@ -11,6 +11,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
SwiftMessages: 077f19126c24033fe24042237ecc20261adb46e4
-PODFILE CHECKSUM: dde250cdcd60ccf6ec0a51da5a633d36b9f83a3b
+PODFILE CHECKSUM: 2eb9a33592d0c52131c37a9dd169a8c4604ffd7b
COCOAPODS: 1.10.0
From af2a69303a8d1f1d9f6fae1bf987ad1d38e7813a Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Thu, 3 Jun 2021 11:33:55 -0500
Subject: [PATCH 02/38] Fix logic that identifies the keyWindow
---
CHANGELOG.md | 3 ++-
SwiftMessages/UIWindow+Extensions.swift | 18 +++++++++++++++---
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f10c7f2..17f749a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,8 @@ All notable changes to this project will be documented in this file.
### Fixes
-* #465 - Fix broken Carthage build. The Carthage build was broken due to the `iMessageDemo` project's use of CocoaPods and the automatically generated `SwiftMessages` framework scheme created by CocoaPods. The podfile was modified to delete this scheme, but Carthage users may need to run `pod install` on the `iMessagesDemo` project, if they have CocoaPods installed, or manually delete the `iMessageDemo/Pods/Pods.xcodeproj/xcuserdata` folder.
+* #466 Alert not shown after Biometry check
+* #465 Fix broken Carthage build. The Carthage build was broken due to the `iMessageDemo` project's use of CocoaPods and the automatically generated `SwiftMessages` framework scheme created by CocoaPods. The podfile was modified to delete this scheme, but Carthage users may need to run `pod install` on the `iMessagesDemo` project, if they have CocoaPods installed, or manually delete the `iMessageDemo/Pods/Pods.xcodeproj/xcuserdata` folder.
## 9.0.2
diff --git a/SwiftMessages/UIWindow+Extensions.swift b/SwiftMessages/UIWindow+Extensions.swift
index d98c6ca..316fcac 100644
--- a/SwiftMessages/UIWindow+Extensions.swift
+++ b/SwiftMessages/UIWindow+Extensions.swift
@@ -13,10 +13,9 @@ extension UIWindow {
static var keyWindow: UIWindow? {
if #available(iOS 13.0, *) {
return UIApplication.shared.connectedScenes
- .filter { $0.activationState == .foregroundActive }
+ .sorted { $0.activationState.sortPriority < $1.activationState.sortPriority }
.compactMap { $0 as? UIWindowScene }
- .first?.windows
- .filter { $0.isKeyWindow }
+ .compactMap { $0.windows.first { $0.isKeyWindow } }
.first
} else {
return UIApplication.shared.keyWindow
@@ -24,3 +23,16 @@ extension UIWindow {
}
#endif
}
+
+@available(iOS 13.0, *)
+private extension UIScene.ActivationState {
+ var sortPriority: Int {
+ switch self {
+ case .foregroundActive: return 1
+ case .foregroundInactive: return 2
+ case .background: return 3
+ case .unattached: return 4
+ @unknown default: return 5
+ }
+ }
+}
From 402984b2171c28038894c73bed4467832041f4c7 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Thu, 3 Jun 2021 12:36:41 -0500
Subject: [PATCH 03/38] =?UTF-8?q?Fix=20467=20-=20don=E2=80=99t=20tell=20th?=
=?UTF-8?q?e=20previous=20window=20to=20become=20visible?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
SwiftMessages/WindowViewController.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SwiftMessages/WindowViewController.swift b/SwiftMessages/WindowViewController.swift
index 96b3009..9c2b721 100644
--- a/SwiftMessages/WindowViewController.swift
+++ b/SwiftMessages/WindowViewController.swift
@@ -59,7 +59,7 @@ open class WindowViewController: UIViewController
func uninstall() {
if window?.isKeyWindow == true {
- previousKeyWindow?.makeKeyAndVisible()
+ previousKeyWindow?.makeKey()
}
if #available(iOS 13, *) {
window?.windowScene = nil
From 2187a0c8f8c8a11aa73f05fa915be3cc9c36f240 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Thu, 3 Jun 2021 12:37:54 -0500
Subject: [PATCH 04/38] Update changelog
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17f749a..d44911c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
### Fixes
+* #467 Lower or equal level window's views disappear upon hide
* #466 Alert not shown after Biometry check
* #465 Fix broken Carthage build. The Carthage build was broken due to the `iMessageDemo` project's use of CocoaPods and the automatically generated `SwiftMessages` framework scheme created by CocoaPods. The podfile was modified to delete this scheme, but Carthage users may need to run `pod install` on the `iMessagesDemo` project, if they have CocoaPods installed, or manually delete the `iMessageDemo/Pods/Pods.xcodeproj/xcuserdata` folder.
From 8cd41df1290aa6f40665eb98aaeb06f59ff3d594 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Tue, 29 Jun 2021 11:29:52 -0500
Subject: [PATCH 05/38] Some minor cleanup
---
SwiftMessages/Animator.swift | 4 ++--
SwiftMessages/TopBottomAnimation.swift | 12 ++++++------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/SwiftMessages/Animator.swift b/SwiftMessages/Animator.swift
index 7d924e2..8207406 100644
--- a/SwiftMessages/Animator.swift
+++ b/SwiftMessages/Animator.swift
@@ -10,7 +10,7 @@ import UIKit
public typealias AnimationCompletion = (_ completed: Bool) -> Void
-public protocol AnimationDelegate: class {
+public protocol AnimationDelegate: AnyObject {
func hide(animator: Animator)
func panStarted(animator: Animator)
func panEnded(animator: Animator)
@@ -58,7 +58,7 @@ public class AnimationContext {
}
}
-public protocol Animator: class {
+public protocol Animator: AnyObject {
/// Adopting classes should declare as `weak`.
var delegate: AnimationDelegate? { get set }
diff --git a/SwiftMessages/TopBottomAnimation.swift b/SwiftMessages/TopBottomAnimation.swift
index d9f1f3a..21b0f27 100644
--- a/SwiftMessages/TopBottomAnimation.swift
+++ b/SwiftMessages/TopBottomAnimation.swift
@@ -19,17 +19,17 @@ public class TopBottomAnimation: NSObject, Animator {
public let style: Style
- open var showDuration: TimeInterval = 0.4
+ public var showDuration: TimeInterval = 0.4
- open var hideDuration: TimeInterval = 0.2
+ public var hideDuration: TimeInterval = 0.2
- open var springDamping: CGFloat = 0.8
+ public var springDamping: CGFloat = 0.8
- open var closeSpeedThreshold: CGFloat = 750.0;
+ public var closeSpeedThreshold: CGFloat = 750.0;
- open var closePercentThreshold: CGFloat = 0.33;
+ public var closePercentThreshold: CGFloat = 0.33;
- open var closeAbsoluteThreshold: CGFloat = 75.0;
+ public var closeAbsoluteThreshold: CGFloat = 75.0;
public private(set) lazy var panGestureRecognizer: UIPanGestureRecognizer = {
let pan = UIPanGestureRecognizer()
From 349fec7674f588d7c32b2aa0c55dfe46eb9f071b Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Tue, 29 Jun 2021 13:48:32 -0500
Subject: [PATCH 06/38] Fix warning
---
SwiftMessages/KeyboardTrackingView.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SwiftMessages/KeyboardTrackingView.swift b/SwiftMessages/KeyboardTrackingView.swift
index 69ce6b0..6af384a 100644
--- a/SwiftMessages/KeyboardTrackingView.swift
+++ b/SwiftMessages/KeyboardTrackingView.swift
@@ -8,7 +8,7 @@
import UIKit
-public protocol KeyboardTrackingViewDelegate: class {
+public protocol KeyboardTrackingViewDelegate: AnyObject {
func keyboardTrackingViewWillChange(change: KeyboardTrackingView.Change, userInfo: [AnyHashable : Any])
func keyboardTrackingViewDidChange(change: KeyboardTrackingView.Change, userInfo: [AnyHashable : Any])
}
From c5026484ff555db961ec549162e4026b017aa6c5 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Fri, 17 Sep 2021 16:42:06 -0500
Subject: [PATCH 07/38] Work/9.0.4 (#479)
* Add dark mode theme
* Remove availability check, which is not supported in iOS 15
* Support Xcode 13 (#478)
* Remove @available from enum cases
* Carthage support
* Refactor
* Remove unnecessary methods
* Code review
Co-authored-by: Timothy Moose
* Prep for release
* Update changelog
Co-authored-by: Kohki Miki
---
CHANGELOG.md | 5 +
SwiftMessages.podspec | 2 +-
SwiftMessages.xcodeproj/project.pbxproj | 10 +-
SwiftMessages/MessageView.swift | 72 +-
.../SwiftMessages.Config+Extensions.swift | 2 +-
SwiftMessages/SwiftMessages.swift | 17 +-
SwiftMessages/WindowScene.swift | 9 +
iMessageDemo/Podfile.lock | 2 +-
iMessageDemo/Pods/Manifest.lock | 2 +-
.../Pods/Pods.xcodeproj/project.pbxproj | 900 +++++++++---------
10 files changed, 550 insertions(+), 471 deletions(-)
create mode 100644 SwiftMessages/WindowScene.swift
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d44911c..ed08715 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 9.0.4
+
+* #471 Xcode 13 issue - Enum cases with associated values cannot be marked potentially unavailable with '@available'
+* Improve colors for dark mode.
+
## 9.0.3
### Fixes
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index a6c018f..688f100 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '9.0.3'
+ spec.version = '9.0.4'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkick.it' }
diff --git a/SwiftMessages.xcodeproj/project.pbxproj b/SwiftMessages.xcodeproj/project.pbxproj
index 5103fcd..b01d9c2 100644
--- a/SwiftMessages.xcodeproj/project.pbxproj
+++ b/SwiftMessages.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 0797E40E26EE12B400691606 /* WindowScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0797E40D26EE12B400691606 /* WindowScene.swift */; };
220655121FAF82B600F4E00F /* MarginAdjustable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */; };
220D386E2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 220D386D2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift */; };
224FB69921153B440081D4DE /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 224FB69821153B440081D4DE /* CALayer+Extensions.swift */; };
@@ -54,7 +55,7 @@
2298C2051EE47DC900E2DDC1 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2041EE47DC900E2DDC1 /* Weak.swift */; };
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2061EE480D000E2DDC1 /* Animator.swift */; };
2298C2091EE486E300E2DDC1 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */; };
- 229F778125FAB1E9008C2ACB /* UIWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */; };
+ 229F778125FAB1E9008C2ACB /* UIWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */; };
22DFC9161EFF30F6001B1CA1 /* CenteredView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22DFC9151EFF30F6001B1CA1 /* CenteredView.xib */; };
22DFC9181F00674E001B1CA1 /* PhysicsPanHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DFC9171F00674E001B1CA1 /* PhysicsPanHandler.swift */; };
22E01F641E74EC8B00ACE19A /* MaskingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22E01F631E74EC8B00ACE19A /* MaskingView.swift */; };
@@ -94,6 +95,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 0797E40D26EE12B400691606 /* WindowScene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowScene.swift; sourceTree = ""; };
220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MarginAdjustable+Extensions.swift"; sourceTree = ""; };
220D386D2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftMessages.Config+Extensions.swift"; sourceTree = ""; };
224FB69821153B440081D4DE /* CALayer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Extensions.swift"; sourceTree = ""; };
@@ -141,7 +143,7 @@
2298C2041EE47DC900E2DDC1 /* Weak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = ""; };
2298C2061EE480D000E2DDC1 /* Animator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animator.swift; sourceTree = ""; };
2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopBottomAnimation.swift; sourceTree = ""; };
- 229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIWindow+Extensions.swift"; sourceTree = ""; };
+ 229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIWindow+Extensions.swift"; sourceTree = ""; };
22A2EA6E24EC6CFA00BB2540 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
22DFC9151EFF30F6001B1CA1 /* CenteredView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = CenteredView.xib; path = Resources/CenteredView.xib; sourceTree = ""; };
22DFC9171F00674E001B1CA1 /* PhysicsPanHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhysicsPanHandler.swift; sourceTree = ""; };
@@ -211,7 +213,7 @@
children = (
220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */,
22774B9F20B5EF2A00813732 /* UIEdgeInsets+Extensions.swift */,
- 229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */,
+ 229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */,
);
name = Extensions;
sourceTree = "";
@@ -304,6 +306,7 @@
2298C2041EE47DC900E2DDC1 /* Weak.swift */,
22F27950210CE25900273E7F /* CornerRoundingView.swift */,
225304652293000C00A03ACF /* KeyboardTrackingView.swift */,
+ 0797E40D26EE12B400691606 /* WindowScene.swift */,
);
name = Base;
sourceTree = "";
@@ -555,6 +558,7 @@
86BBA9081D5E040C00FE8F16 /* Error.swift in Sources */,
2298C2091EE486E300E2DDC1 /* TopBottomAnimation.swift in Sources */,
86589D471D64B6E40041676C /* BaseView.swift in Sources */,
+ 0797E40E26EE12B400691606 /* WindowScene.swift in Sources */,
225304622290C76E00A03ACF /* NSLayoutConstraint+Extensions.swift in Sources */,
86BBA9071D5E040C00FE8F16 /* MarginAdjustable.swift in Sources */,
867BED211D622793005212E3 /* BackgroundViewable.swift in Sources */,
diff --git a/SwiftMessages/MessageView.swift b/SwiftMessages/MessageView.swift
index d9be31d..c71141a 100644
--- a/SwiftMessages/MessageView.swift
+++ b/SwiftMessages/MessageView.swift
@@ -251,24 +251,72 @@ extension MessageView {
*/
public func configureTheme(_ theme: Theme, iconStyle: IconStyle = .default) {
let iconImage = iconStyle.image(theme: theme)
+ let backgroundColor: UIColor
+ let foregroundColor: UIColor
+ let defaultBackgroundColor: UIColor
+ let defaultForegroundColor: UIColor
switch theme {
case .info:
- let backgroundColor = UIColor(red: 225.0/255.0, green: 225.0/255.0, blue: 225.0/255.0, alpha: 1.0)
- let foregroundColor = UIColor.darkText
- configureTheme(backgroundColor: backgroundColor, foregroundColor: foregroundColor, iconImage: iconImage)
+ defaultBackgroundColor = UIColor(red: 225.0/255.0, green: 225.0/255.0, blue: 225.0/255.0, alpha: 1.0)
+ defaultForegroundColor = UIColor.darkText
case .success:
- let backgroundColor = UIColor(red: 97.0/255.0, green: 161.0/255.0, blue: 23.0/255.0, alpha: 1.0)
- let foregroundColor = UIColor.white
- configureTheme(backgroundColor: backgroundColor, foregroundColor: foregroundColor, iconImage: iconImage)
+ defaultBackgroundColor = UIColor(red: 97.0/255.0, green: 161.0/255.0, blue: 23.0/255.0, alpha: 1.0)
+ defaultForegroundColor = UIColor.white
case .warning:
- let backgroundColor = UIColor(red: 238.0/255.0, green: 189.0/255.0, blue: 34.0/255.0, alpha: 1.0)
- let foregroundColor = UIColor.white
- configureTheme(backgroundColor: backgroundColor, foregroundColor: foregroundColor, iconImage: iconImage)
+ defaultBackgroundColor = UIColor(red: 246.0/255.0, green: 197.0/255.0, blue: 44.0/255.0, alpha: 1.0)
+ defaultForegroundColor = UIColor.white
case .error:
- let backgroundColor = UIColor(red: 249.0/255.0, green: 66.0/255.0, blue: 47.0/255.0, alpha: 1.0)
- let foregroundColor = UIColor.white
- configureTheme(backgroundColor: backgroundColor, foregroundColor: foregroundColor, iconImage: iconImage)
+ defaultBackgroundColor = UIColor(red: 249.0/255.0, green: 66.0/255.0, blue: 47.0/255.0, alpha: 1.0)
+ defaultForegroundColor = UIColor.white
}
+ if #available(iOS 13.0, *) {
+ switch theme {
+ case .info:
+ backgroundColor = UIColor {
+ switch $0.userInterfaceStyle {
+ case .dark, .unspecified: return UIColor(red: 125/255.0, green: 125/255.0, blue: 125/255.0, alpha: 1.0)
+ case .light: fallthrough
+ @unknown default:
+ return defaultBackgroundColor
+ }
+ }
+ foregroundColor = .label
+ case .success:
+ backgroundColor = UIColor {
+ switch $0.userInterfaceStyle {
+ case .dark, .unspecified: return UIColor(red: 55/255.0, green: 122/255.0, blue: 0/255.0, alpha: 1.0)
+ case .light: fallthrough
+ @unknown default:
+ return defaultBackgroundColor
+ }
+ }
+ foregroundColor = .white
+ case .warning:
+ backgroundColor = UIColor {
+ switch $0.userInterfaceStyle {
+ case .dark, .unspecified: return UIColor(red: 239/255.0, green: 184/255.0, blue: 10/255.0, alpha: 1.0)
+ case .light: fallthrough
+ @unknown default:
+ return defaultBackgroundColor
+ }
+ }
+ foregroundColor = .white
+ case .error:
+ backgroundColor = UIColor {
+ switch $0.userInterfaceStyle {
+ case .dark, .unspecified: return UIColor(red: 195/255.0, green: 12/255.0, blue: 12/255.0, alpha: 1.0)
+ case .light: fallthrough
+ @unknown default:
+ return defaultBackgroundColor
+ }
+ }
+ foregroundColor = .white
+ }
+ } else {
+ backgroundColor = defaultBackgroundColor
+ foregroundColor = defaultForegroundColor
+ }
+ configureTheme(backgroundColor: backgroundColor, foregroundColor: foregroundColor, iconImage: iconImage)
}
/**
diff --git a/SwiftMessages/SwiftMessages.Config+Extensions.swift b/SwiftMessages/SwiftMessages.Config+Extensions.swift
index 9682b5b..ac0475d 100644
--- a/SwiftMessages/SwiftMessages.Config+Extensions.swift
+++ b/SwiftMessages/SwiftMessages.Config+Extensions.swift
@@ -20,7 +20,7 @@ extension SwiftMessages.Config {
@available (iOS 13.0, *)
var windowScene: UIWindowScene? {
switch presentationContext {
- case .windowScene(let scene, _): return scene
+ case .windowScene(let scene, _): return scene as? UIWindowScene
default:
#if SWIFTMESSAGES_APP_EXTENSIONS
return nil
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index dfae859..7c0042f 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -77,10 +77,10 @@ open class SwiftMessages {
of any message view that adopts the `MarginInsetting` protocol (as `MessageView` does)
to account for the status bar. As of iOS 13, windows can no longer cover the
status bar. The only alternative is to set `Config.prefersStatusBarHidden = true`
- to hide it.
+ to hide it. The `WindowScene` protocol works around the change in Xcode 13 that prevents
+ using `@availability` attribute with `enum` cases containing associated values.
*/
- @available(iOS 13.0, *)
- case windowScene(_: UIWindowScene, windowLevel: UIWindow.Level)
+ case windowScene(_: WindowScene, windowLevel: UIWindow.Level)
/**
Displays the message view under navigation bars and tab bars if an
@@ -248,7 +248,16 @@ open class SwiftMessages {
Specifies how the container for presenting the message view
is selected. The default is `.Automatic`.
*/
- public var presentationContext = PresentationContext.automatic
+ public var presentationContext = PresentationContext.automatic {
+ didSet {
+ if case .windowScene = presentationContext {
+ guard #available(iOS 13.0, *) else {
+ assertionFailure("windowScene is not supported below iOS 13.0.")
+ return
+ }
+ }
+ }
+ }
/**
Specifies the duration of the message view's time on screen before it is
diff --git a/SwiftMessages/WindowScene.swift b/SwiftMessages/WindowScene.swift
new file mode 100644
index 0000000..a3bbb4c
--- /dev/null
+++ b/SwiftMessages/WindowScene.swift
@@ -0,0 +1,9 @@
+import Foundation
+import UIKit
+
+/// A workaround for the change in Xcode 13 that prevents using `@availability` attribute
+/// with `enum` cases containing associated values.
+public protocol WindowScene {}
+
+@available(iOS 13.0, *)
+extension UIWindowScene: WindowScene {}
diff --git a/iMessageDemo/Podfile.lock b/iMessageDemo/Podfile.lock
index 54bd951..7162a91 100644
--- a/iMessageDemo/Podfile.lock
+++ b/iMessageDemo/Podfile.lock
@@ -13,4 +13,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 2eb9a33592d0c52131c37a9dd169a8c4604ffd7b
-COCOAPODS: 1.10.0
+COCOAPODS: 1.10.1
diff --git a/iMessageDemo/Pods/Manifest.lock b/iMessageDemo/Pods/Manifest.lock
index 54bd951..7162a91 100644
--- a/iMessageDemo/Pods/Manifest.lock
+++ b/iMessageDemo/Pods/Manifest.lock
@@ -13,4 +13,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 2eb9a33592d0c52131c37a9dd169a8c4604ffd7b
-COCOAPODS: 1.10.0
+COCOAPODS: 1.10.1
diff --git a/iMessageDemo/Pods/Pods.xcodeproj/project.pbxproj b/iMessageDemo/Pods/Pods.xcodeproj/project.pbxproj
index 468092a..0d6bbc2 100644
--- a/iMessageDemo/Pods/Pods.xcodeproj/project.pbxproj
+++ b/iMessageDemo/Pods/Pods.xcodeproj/project.pbxproj
@@ -7,106 +7,107 @@
objects = {
/* Begin PBXBuildFile section */
- 00468531530F8A70E3D83622BD482026 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E6941E59EF0D89949E3DF3D89488430 /* Weak.swift */; };
- 0303F738260F2C9BAE20B79DE84E82BC /* PhysicsPanHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2337E6D5F621F3CE9A1E3761984EBE87 /* PhysicsPanHandler.swift */; };
- 0B42A04122166EAD384BCE37FD450FAF /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8901520225CE89F44E6DE88688F29C10 /* MessageView.swift */; };
- 0CE00BF7FB0F6376D89B0AFF1CFD7510 /* PassthroughView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C557E1DC95AFA417E94ED01301F9F2 /* PassthroughView.swift */; };
- 0E7AE1B3CE2734B39ACCE812B4320B44 /* MarginAdjustable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B91AD9D9E743D17D553D48103BE27C46 /* MarginAdjustable+Extensions.swift */; };
- 138A7742F76993FB9EE3555FD2808562 /* successIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = A80433B71162112A79043CB64261DB51 /* successIconLight.png */; };
- 16047C447B00FAA7F42764EC4167C33B /* NSLayoutConstraint+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0970322A5DD8B4A8373C35ED051DE156 /* NSLayoutConstraint+Extensions.swift */; };
- 1F4159921A25C7B2A0E9C587387D829C /* errorIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1B04615682E8B787C964824435BC6616 /* errorIconLight@2x.png */; };
- 1F6162906845BE72A5BCDAF14D6E14B9 /* warningIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = 4512DEEA328AB0AAA95D77C84C89E02C /* warningIconSubtle.png */; };
- 2181E713FC7C00EE871FDA6CB62C7E8C /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5607E285A85AC7163B0B8FD447FD27E /* Theme.swift */; };
- 2558CABB502ED605BC21DCFC55A9C0B7 /* MessageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = AE62AA801971C530345349D18AFCCB82 /* MessageView.xib */; };
- 2B23A9DFDAACFE9C0AD5EB6899E63475 /* infoIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4FE466AC4123CDAE9FDA9FCF4FB9CC60 /* infoIconSubtle@2x.png */; };
- 33785D52B8888C2EA02BD0495408E352 /* successIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 72A865FFBAE49EF66A35CB9D709E8D7E /* successIconLight@3x.png */; };
- 3505AB28DBFA49FBE5C8250F3E067E60 /* KeyboardTrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536660614870EA0E051BF6BDDF495798 /* KeyboardTrackingView.swift */; };
- 365594AAFDD4EE947EB33E6E86A8578E /* errorIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = A850F76D7E3FEDC20FFB877454069171 /* errorIconSubtle.png */; };
- 425F2D4CE95436680D77C263FF15221B /* SwiftMessages_SwiftMessages.bundle in Resources */ = {isa = PBXBuildFile; fileRef = BEBF018059B0DFCAC8494ABD1C578AD9 /* SwiftMessages_SwiftMessages.bundle */; };
- 4267FACE20717FF3F51C2ACAB8C395A4 /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D0E8B0020635F606875DD02735C502 /* BaseView.swift */; };
- 44150A4B5B2D251FCBB6CA07DC9872B5 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 267E35F9851AAE50DFB8FA0DCA7F2980 /* Animator.swift */; };
- 447E8A096C1ABD2E0AC9674E65A827E3 /* warningIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 0259757860B26C6072E2640B84EC6D45 /* warningIcon.png */; };
- 44C0F194D748EE88027414A5B2094E9B /* successIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C8155ED78358FA5CF39089176FBDE501 /* successIcon@3x.png */; };
- 461760E2818D72B948B60B4835E7B1ED /* NSBundle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FCF161BD9F1C2CAAFBCADE5E59BD3FD /* NSBundle+Extensions.swift */; };
- 462CDC24C5C8DD6905C4112B6B4BD2ED /* successIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = FC73E6C784AF6CA1F956F57F82ED2803 /* successIcon.png */; };
+ 00764FFD14D83F4ABEC0D4D53D48080A /* SwiftMessages-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6E00017F9E79F6D4926E9CB43A66DF /* SwiftMessages-dummy.m */; };
+ 02905CCF79B22A773CD0BA32EDB9648A /* AccessibleMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0201BC51C7CA061016B619400691A139 /* AccessibleMessage.swift */; };
+ 05D9CBEC9488BAA2962B174703D25218 /* PassthroughWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A331C2E0BE2AE2118D65AA1F12519F2 /* PassthroughWindow.swift */; };
+ 0C55441C4B8356AC1244EED7684E1783 /* MaskingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D69BE188B82D84ED23AC4E27BAB61D /* MaskingView.swift */; };
+ 11DE7052A0A78D6E27D8D129D413DAF6 /* errorIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 7100245A2722BD53D5B3927ED649069F /* errorIconLight.png */; };
+ 13620BA62A66C8C6F9345341BCD111ED /* KeyboardTrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90AC342C6F09BF7715D4FB95512DD68A /* KeyboardTrackingView.swift */; };
+ 1662CF43016AFC375200E466F130D90E /* warningIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = 860D833A7A1B108A89ED34AD74778AC0 /* warningIconSubtle.png */; };
+ 28F2E02536C48A4B661D6D8AAFB5D37E /* CornerRoundingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 007ACA6F89C6C856F78352A086F3B8EA /* CornerRoundingView.swift */; };
+ 30D023ABC2D1CFC829CF04360768B7F8 /* StatusLine.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E2FE4DB6869F330F19A3A5459AAFFFB /* StatusLine.xib */; };
+ 34CB62900FA4AAC84745C7E958657648 /* errorIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D30B2BF71F9D2C63C2D202C99827CDC1 /* errorIconLight@2x.png */; };
+ 3A8B97D9210D1E2BEED5E1159BE7E748 /* warningIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = C56AB83FDAB8D6A1328E7EECCAD99A69 /* warningIconLight.png */; };
+ 3BFC9F0FAF0757A2D3574ED4E4100D57 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 467EAD44C7F625F384822180F004E64F /* CALayer+Extensions.swift */; };
+ 4256FC87C833154DCDEE84CD98F910D7 /* Identifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFD31968BF9DF7A9E25A136DF254F3A9 /* Identifiable.swift */; };
46CCA4DDFDBBDD2A9426BB96C08E4255 /* Pods-iMessageExtensionDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F40CA14AD738DD186B4DA8FD14AE5BD /* Pods-iMessageExtensionDemo-dummy.m */; };
- 492F085489FCAB0EEBE74B098F7D3F4D /* StatusLine.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7A6801849037A728E9BC50E06CE8AD2F /* StatusLine.xib */; };
- 4C78ED4E1780F5609E25CE03429C1DE4 /* errorIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 848251807107C20960A3DABAB27F7475 /* errorIconLight@3x.png */; };
- 4DB5D1FB08693DDDC32BCF19CC1B1AA0 /* warningIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 874D31DE863C88B1D699E1EBFBE0641B /* warningIconLight@2x.png */; };
- 4E703B2A80C64CF1142872BE31263940 /* errorIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 0892E032AE12339D1AD84BDCC78A3C07 /* errorIconLight.png */; };
- 4E9CCFC43646B6CDBE3B787AB09A0147 /* CardView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 42F1E753E61B6EDED3908AC66994649C /* CardView.xib */; };
- 5260BD3289BAC54A20457099C4A57EFF /* errorIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 9D1FEAC04417D847EDC10783E054988F /* errorIcon.png */; };
- 52F4ED7F78829270B2AFE5EDBA9EEE2F /* UIEdgeInsets+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9A13E69643D651322647C28E3F9E9C9 /* UIEdgeInsets+Extensions.swift */; };
+ 47F1E9964F1112D0E8F0FF8C25204E2F /* SwiftMessages_SwiftMessages.bundle in Resources */ = {isa = PBXBuildFile; fileRef = BEBF018059B0DFCAC8494ABD1C578AD9 /* SwiftMessages_SwiftMessages.bundle */; };
+ 4889E21A2024267A944084FB851200B5 /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7EE64CFE0084CF5213A03AF29A668ED /* BaseView.swift */; };
+ 4B907B48F27F55DF65CC1553C7C26942 /* infoIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 730840765E737D45772EBE66DB8A6D2E /* infoIconLight.png */; };
+ 4B9459A11E2A1D65AE3224CF468AE8CA /* warningIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7C4DF53A4B44C246968618BF25962786 /* warningIconLight@3x.png */; };
+ 4E82DE4069FECF20D0E29CB06A0FCFB6 /* SwiftMessages.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6264350B8D100D5B5C5EEEC316933D /* SwiftMessages.swift */; };
+ 531825CE7041C5C1BA684BDA9C8972A3 /* UIEdgeInsets+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36F7B24601DF4C00B14EC8CE2D4A48DC /* UIEdgeInsets+Extensions.swift */; };
560A2B1056FEFE42AC6524A2A1742CA2 /* Pods-iMessageExtensionDemo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAB201AD00CAB811B045E2FFB5C03A8 /* Pods-iMessageExtensionDemo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 57072960EA4F0D307171ED90697D3FAF /* TabView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B7FD0618783A3E6B90D3A3323633959F /* TabView.xib */; };
- 5720D965B3CE67653082137053FBEC9C /* infoIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 9C110C924ED12D2D32ECC27503018A31 /* infoIconLight.png */; };
- 5750C24C3A9CAE11C7E36B37434912D0 /* MaskingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CF61FDEFE095F0486E9914F2262ADB9 /* MaskingView.swift */; };
- 5DF3F4808ED4A6932839C11A5D742B93 /* successIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 54B278C80D821C120FA70ABB6CAF1F46 /* successIconSubtle@3x.png */; };
- 6320AE79D41E8D1F52AF66A670542561 /* CornerRoundingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F8D7902822221456B697BB41111E450 /* CornerRoundingView.swift */; };
- 64595C731B826EB19E9757D524E0BF76 /* warningIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CFBBC25592C97C925B6F81B53BE57CB /* warningIcon@3x.png */; };
- 683A7897D1E9A73F4717198B1C054D29 /* errorIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 60268FE48AA4DC9FD5060B1E5CE68453 /* errorIcon@2x.png */; };
- 6A539682FDDA0E5DA23E1B5F2BA133C1 /* errorIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B6DEAADC09FEB1A8D5B90108103EE478 /* errorIcon@3x.png */; };
- 6C7DAA6A68AFDACD67F2C127CEF4DD6F /* UIWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 397C8F928170138667B9326F9655D75D /* UIWindow+Extensions.swift */; };
- 755DA479621A9D2BB8B84540DE648A7A /* warningIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 667DECE93ABCC6869A071FFEB0F83EA5 /* warningIconSubtle@3x.png */; };
- 7ACCA07CCFD868899D61F4B4AE5774DB /* infoIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B7213B7DC5432DA2B272F25E17AA364 /* infoIconSubtle@3x.png */; };
+ 56F9865D99C4FADB8FC83CA548F82110 /* successIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17ADABD24F805C5F7FF62167E7ABEF0A /* successIconSubtle@3x.png */; };
+ 5B9F8D117AF7BEDDB511EF475FA25995 /* infoIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 48DC3BADDA3A20F2AEB8585117DAFA0D /* infoIcon@3x.png */; };
+ 5CA294C8D3BBC986CF0703D4E2A28687 /* SwiftMessages.Config+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A16E25077F8D76288BE678E6AC1C884 /* SwiftMessages.Config+Extensions.swift */; };
+ 61548914728141D77F87E31B3911CE7E /* successIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 91D9224F29E092950BADC27C979E10CC /* successIconSubtle@2x.png */; };
+ 62B05E0AC13A614A2F8D8A1BE9B514B3 /* infoIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = F9CDB54E629D60FF881DF27B949F4C2D /* infoIconSubtle.png */; };
+ 632538BAE98BBFD6CED58844B7611C24 /* MarginAdjustable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C8214A441D845A4A4DD6570FD5D458F /* MarginAdjustable+Extensions.swift */; };
+ 6685298EC64F73060F5DB1A841375069 /* warningIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8AD355ED684A939F2A4E333F95E8AC31 /* warningIconSubtle@2x.png */; };
+ 668EDAB86421216BEF7D3F932851A834 /* errorIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 468D9889455DE51BD5BBC2360BDBB877 /* errorIconSubtle@2x.png */; };
+ 6A933CC66558A1FB0AB0BC76F9807E71 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF65ECDAFAD03A79B5571C6F66D8F35 /* TopBottomAnimation.swift */; };
+ 755898E0E511FC5AE881403BEF2A02FC /* successIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D032FCFAE6607CF878AA2F35EF93146C /* successIcon@3x.png */; };
+ 7905F28CF56E06626475EBA3EB73D905 /* MarginAdjustable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68834C60D0C5EA751E9F12E427C5FFE /* MarginAdjustable.swift */; };
+ 7B352022AFCAA5C364E1E2F61290628E /* MessageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B8A4CCB4B08D2D3BE586212AB4167DC2 /* MessageView.xib */; };
7BC52E6F0D9D19B05E62E623E53FCE82 /* Pods-iMessageDemo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D0ECE831FB5E0EE1D68E837671320C7 /* Pods-iMessageDemo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 7E5ADF1F3B6849D5A0DF8E2B9C1861C5 /* PhysicsAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE3BED1799B2F867F5C984C2A051E36A /* PhysicsAnimation.swift */; };
- 8148CD8F2B38FB38B7B9CCC12E93ECFB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
- 89ACEF0F9E524BD21D6C2460FEC375F8 /* warningIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = ED86D7B42F55040DCE162653FB3C7EDB /* warningIconSubtle@2x.png */; };
- 966B9C1EE6B73E430F03D51A4FD26D20 /* MarginAdjustable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6C56947CAF8EFCC7858E1E2F1273427 /* MarginAdjustable.swift */; };
- 9CEE0E569456D932AA34329D2038DF98 /* SwiftMessagesSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFFDB7DDC6B6B064B9D12281E2531BFA /* SwiftMessagesSegue.swift */; };
- 9E3D4CA932041E99B6FD56D4E79A726F /* SwiftMessages-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C614EECDDFE644AF0BF7CB16A3D74404 /* SwiftMessages-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 9FFE65CB6E825ECAE4838D53E7BA4C06 /* infoIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4412F313361EFEE7A0193533A5AC5999 /* infoIconLight@3x.png */; };
- A11E7A379B288CCA3AE6785B83FA4316 /* AccessibleMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDAF8A2C45FDDDFD5AFA59203137551 /* AccessibleMessage.swift */; };
- A1734DB0A8A558B2397AF54E63F64416 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8341EF04E2B20C2BF6D4AF2240F80A56 /* Error.swift */; };
+ 80DE92140CF5AFB5224643FA952EFDEA /* successIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 52F1CA85E0EED7D94FE0036BC92EB3EC /* successIconLight.png */; };
+ 8F1BAB73C85D58C56F55E91573C2E7EF /* infoIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = E41BFEB1BFF85793C0DB85F95184B752 /* infoIcon.png */; };
+ 926907C8DCE76101AF5CB470DB7797D7 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D73E42D996B226222A4EBA46F7DC6D /* Weak.swift */; };
+ 934A8FA91D6518CB70273B73F8038ECA /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 778F6E19CE49B8EDBAC2FCCD8195A55B /* MessageView.swift */; };
+ 946185C05E253C9E47ABCD9EDE7E14D1 /* warningIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 29A39558830996C4F54686A1748B74B1 /* warningIcon@2x.png */; };
+ 94B459D6CBA2A01D2B8174D138C30920 /* UIWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753B78926D6BB175E96AB6E6F3514E87 /* UIWindow+Extensions.swift */; };
+ 95DD12BBA763163407787AB32AAF8E56 /* successIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = A342E145FED9CD8DB4F464D110203E7C /* successIcon.png */; };
+ 9B1E91097B4BD539EBCBBCC3C62CB75A /* errorIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = DEC0A6AE07C3285CA508F8FA3F4FE27D /* errorIcon.png */; };
+ 9B1F7A4183F57B0AA9DD02624BD8855B /* PhysicsPanHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDEF50CAF615897F7A8540579B445634 /* PhysicsPanHandler.swift */; };
+ 9B89868BA12CC4E1D9F116F663E56695 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24021DCE87BE9746D1DFB436C0A3AF7A /* Theme.swift */; };
+ 9CFE7FFD7DDE28FCDA72647F2DB82837 /* infoIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 45844D489A130BA91E91E7CDD4969862 /* infoIconSubtle@2x.png */; };
+ 9DA2F2EED5C99045AF44FF410A012F9D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
+ 9DBD1955C7C621D9DCBE03D2161C91A9 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D261B7BE0088C26BF6744F27B894492A /* UIViewController+Extensions.swift */; };
+ 9F0473806FD530165403E47E834790C2 /* CenteredView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 787EE6DA4FBC3BF85ED2CF0BB6EBF494 /* CenteredView.xib */; };
+ 9FA48348FB5F41070356A75237367D6D /* TabView.xib in Resources */ = {isa = PBXBuildFile; fileRef = EABF0CEB87991D02E13306975A8E80BB /* TabView.xib */; };
+ A67A9ADFBCB364FCEF1BD92FF20B285C /* CardView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 705B5AF043D00B6538599B4EB1ECD77C /* CardView.xib */; };
A9EB0C8E49AB748B05CF7941ACAF8475 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
- AC4F13F50EB63B484292D67692BC1F9D /* successIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DC54BB09EFDFEDE11F484FE73BEDC60 /* successIconSubtle.png */; };
- B2862C6DDAA6543BB2C8F4541F044564 /* SwiftMessages.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3216CF40D770C387D45C3B4AF2CC9E0 /* SwiftMessages.swift */; };
- B2CC8FF0F9FF3FE929180CDB32B69F18 /* infoIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F7004673F1B51EEC365B32F0E060E564 /* infoIcon@2x.png */; };
- B42A7A38C8014DBDE2632B909F71C355 /* successIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 62755A788F910CA88887B6F63BBC545F /* successIcon@2x.png */; };
- B60094A8D1343B7351F0EF9C51F2F0DB /* infoIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 337B3108412E3812254B85BCC4F90EB8 /* infoIcon@3x.png */; };
- BB16D1E73A5D6B27DC4212926986107F /* warningIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BFEF746702215C33B51BEE64C4E48F0A /* warningIcon@2x.png */; };
- BBFE3BAFFCE67F4EACE0C67A7B7FFC3A /* successIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0B3A169D83BDA3613A661845D1607FC0 /* successIconSubtle@2x.png */; };
- BC4618CE535404A9540D4D110B5767A1 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 396FCF260E9C2B3F11080A91E3D72334 /* TopBottomAnimation.swift */; };
- BDCF9C5E4F88B2B0AB6D4595E5A281E1 /* successIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F898B2AC5C3404C266BBCA3B6D22B5E4 /* successIconLight@2x.png */; };
+ A9FFA668A7F81F50FBDCDCE26E891C8B /* errorIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = E0E4D99C4F78B9BA011D83FE63EE0946 /* errorIcon@3x.png */; };
+ AC0A9B473B11FFF4BDEC0A0598795843 /* WindowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AA0E820F1C1AA219C066370332845A /* WindowViewController.swift */; };
+ AD7F228AE0628DAAE4497493335D2BF7 /* SwiftMessages-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CBEAC9D0EF4113C3FD3B15F511A92D0 /* SwiftMessages-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ ADA044C43E517C5F0603B2A0AFB19860 /* successIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 760BFB41B33B6ED91B3FFD68D39083A0 /* successIconLight@2x.png */; };
+ ADA91E8F5FDCD2EEC3D3B18A5B375C2C /* errorIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DF3DE135AB5C5C789CABAECC704CE907 /* errorIcon@2x.png */; };
+ ADE48B746D5BB28EC33B403E1E12E0FE /* infoIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E936107A7CF9821DCBFFAF50D916F1E6 /* infoIcon@2x.png */; };
+ AF34F903519AF36E07A90EF1BD703777 /* WindowScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DEFE9675E5359A46A443182F127F06 /* WindowScene.swift */; };
+ B02B2EAB7B8662AA27D91403BF9AAF36 /* warningIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A0EE84E98A10805A2D64B836C465ED11 /* warningIconSubtle@3x.png */; };
+ B4D338F85183163DC8CAB8A5864C9015 /* infoIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 676F359BE8561CF7512DB8B42CD7873A /* infoIconLight@3x.png */; };
+ B520EDE98BD17CE5676F52A77139A933 /* NSLayoutConstraint+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6924EB5FC7236837637AE8F409000A /* NSLayoutConstraint+Extensions.swift */; };
+ B679ED0F79CAF552C081588F3B63B91A /* warningIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0038C9A582787F9882258E8D1080EACF /* warningIcon@3x.png */; };
+ C11CE75FD2DFCDF3B72D8D16280A2054 /* successIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 79D34B3C6875DA0279CB934C84CD000B /* successIcon@2x.png */; };
C384FB76A48C06F7581D0F7850F2F4F1 /* Pods-iMessageDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 14BF989232A1D55A0FDAAB70B5A8E1BF /* Pods-iMessageDemo-dummy.m */; };
C3CDAED707B153A58674CB1AC4A33FB2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
- C4598A458697C49C961BFDCD090B3A8F /* infoIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = 06F2F626BE8417F1806CC5B17F210C90 /* infoIconSubtle.png */; };
- C5FFE932D5EBE2CC8F2ABFEA893D8E9C /* infoIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 70E7AB099F856140EF93D5B94A967418 /* infoIcon.png */; };
- C6E73F201545CF5ED055C69CD4DB2EFF /* warningIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C17CFEF9B761A322945F74D86CA88036 /* warningIconLight@3x.png */; };
- C8F46E0A5853739D3F632B4828FDE9CC /* PassthroughWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 382E6375390EBB09F829519F8ACCB7D7 /* PassthroughWindow.swift */; };
- CCF5CC8F6022DFD410DDCC99A90D58B0 /* warningIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 79E38069364BC5DF4EA88F352E28B242 /* warningIconLight.png */; };
- D49E06426C51C49E9058371138972A69 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B5EF40CEC1F6DB23F428DC159D4BC2 /* CALayer+Extensions.swift */; };
- D61D59BCDFD2C3C7993CFE883DE60692 /* infoIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6516EE9BFCB9C53C151359F9D0247562 /* infoIconLight@2x.png */; };
- D8BDC20F1566606BF64001B6E96B14B6 /* errorIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 453BC098B6A052020C40DE576F684C7B /* errorIconSubtle@3x.png */; };
- D9077478C2FCD7C3DD1EBE9373281728 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15C4C88778A19C193D1EC77FA77BAE4C /* UIViewController+Extensions.swift */; };
- E88597F65A00A5AF50EEF2ABA2392B2F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D245E0514AAC1A2B9A6D5EA2F383E90F /* UIKit.framework */; };
- E94E8711BDDA31B178AA032D3346C307 /* BackgroundViewable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAB58A9F688DD39112E6CDF20C8969C0 /* BackgroundViewable.swift */; };
- EDA146BF3FF59593677F8B2AA785D8A5 /* errorIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3C313FB1D33EF4B477FD5D3D6179A8BE /* errorIconSubtle@2x.png */; };
- F27E3EEAFDDAA6CB4E7407D6A46DAA5D /* CenteredView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3DF091E68C4659506DB08B0876BD274C /* CenteredView.xib */; };
- F50FE2EE47422AD39AC8F7F115081E7E /* SwiftMessages.Config+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3C32E945AE3E6394EF85CD6BEC714B4 /* SwiftMessages.Config+Extensions.swift */; };
- F5642C087197B9033252FF10FBA92B59 /* WindowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8566413BFA3FE6827E63E30515C9B3 /* WindowViewController.swift */; };
- FA6CA270F521DF68A75E527954A2DDAD /* SwiftMessages-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A2F9031B7FA82A17F04D4403091DF836 /* SwiftMessages-dummy.m */; };
- FCB6832EB4D32EF085E770E8B4A9BC2C /* Identifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C0DE01AB7D0935933E7AFBDF2945814 /* Identifiable.swift */; };
- FF01BC94FADD5A72282AEE043DF523A7 /* Presenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A965DD26246DCA8CE39FBAB348ABA24 /* Presenter.swift */; };
+ C418A50F3C321227B0C6BE1D793680D4 /* successIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA199E6F18AB8900B5400EBA0EB32765 /* successIconLight@3x.png */; };
+ C739607C022819840C267A0B4A7B2FD9 /* SwiftMessagesSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF27E3EF103BACDEE8CA842B2C90C8CA /* SwiftMessagesSegue.swift */; };
+ C826D41BE5AF283B12C122AEF9640C99 /* infoIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C9F5DBB6D77B1E61E9BB1A722A4E1823 /* infoIconSubtle@3x.png */; };
+ CC9369D0A5F8715733A4D517E45A3B63 /* infoIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8315EA451FE61625920FEF68174A0D22 /* infoIconLight@2x.png */; };
+ CD480EEF400EC9B894F3292506BF0179 /* successIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = B031268635405AA009D05130C0FC253C /* successIconSubtle.png */; };
+ D34D8255545B84A38C98D2DBB2F12CC5 /* PassthroughView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E03CBB908F2EC39AA5DA7AF04E1BDDD6 /* PassthroughView.swift */; };
+ DE23509CED3A1E62F60E7E4BD6D38A35 /* BackgroundViewable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C706F1F1C6B3CE84445485C8577D5388 /* BackgroundViewable.swift */; };
+ DECF1F62709D95EF5B48628A97B3CF98 /* warningIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 3259F99D03B6D738D7F47A625E7BD3BE /* warningIcon.png */; };
+ E70A6E572A6DD457A766908E3ADCF49B /* errorIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = C787DA4E67B952C984FF5B065E0A2FF7 /* errorIconSubtle.png */; };
+ E8174481BFB4559462F82062D85C0376 /* warningIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FFB0D50D01FFFA3FC2099E395029AE68 /* warningIconLight@2x.png */; };
+ ECE268E9A63198F53B3F0337B3EA8AF3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D245E0514AAC1A2B9A6D5EA2F383E90F /* UIKit.framework */; };
+ F05B5437AFF475FE8811E2A8A734920F /* NSBundle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E2EB968B30DE56F38B5FCFFEDE9F88F /* NSBundle+Extensions.swift */; };
+ F4BE83FBD5001DEDF6736E69ADA6D79B /* Presenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F513F2674553CBC247EE4B24EA25C99C /* Presenter.swift */; };
+ F69D9D53A5500A42D4B41097537628E5 /* errorIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = E31D045D9E355D4F7F75564026B2051A /* errorIconSubtle@3x.png */; };
+ F75A8D3DA9B4787BEEEBF3F784D5CDEF /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D219D80184B8ED97808EE17507B213A /* Animator.swift */; };
+ F9A111F30C3B26D0A35B0829EED70D26 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E610C06F5B006DE57F34D5994532FB /* Error.swift */; };
+ FA02B47E32DD9BEAAB8A2D1B66F697D5 /* PhysicsAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D2B448BE319CF56A38E222C0B7DF4CB /* PhysicsAnimation.swift */; };
+ FDC2C20416D7EBF959A461E25FAFB16E /* errorIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D34E3F2A49E9024A96334DA4147F27B /* errorIconLight@3x.png */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
- 141E78A8858DBF8B2695DFEDCBDF5158 /* PBXContainerItemProxy */ = {
+ 4B785BB517DA1D687C0B772C77660019 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = 1FC5E8328653C350899229BDF89FACE5;
- remoteInfo = "SwiftMessages-SwiftMessages_SwiftMessages";
+ remoteGlobalIDString = DAB613A18652334F6BFC5F27BADF515D;
+ remoteInfo = SwiftMessages;
};
- 4DB1DDB02425E67ED85C70C3B138E205 /* PBXContainerItemProxy */ = {
+ D19F271ED5B0FED7305E55070B415EDB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = DAB613A18652334F6BFC5F27BADF515D;
- remoteInfo = SwiftMessages;
+ remoteGlobalIDString = 1FC5E8328653C350899229BDF89FACE5;
+ remoteInfo = "SwiftMessages-SwiftMessages_SwiftMessages";
};
- 900F05D1477FFAB64FF410CBB6B9B74D /* PBXContainerItemProxy */ = {
+ DA9FA5DB745280F35DD4EFAC9A7A4FD7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
@@ -116,112 +117,113 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- 0259757860B26C6072E2640B84EC6D45 /* warningIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIcon.png; path = SwiftMessages/Resources/warningIcon.png; sourceTree = ""; };
- 06F2F626BE8417F1806CC5B17F210C90 /* infoIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = infoIconSubtle.png; path = SwiftMessages/Resources/infoIconSubtle.png; sourceTree = ""; };
- 0892E032AE12339D1AD84BDCC78A3C07 /* errorIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = errorIconLight.png; path = SwiftMessages/Resources/errorIconLight.png; sourceTree = ""; };
+ 0038C9A582787F9882258E8D1080EACF /* warningIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIcon@3x.png"; path = "SwiftMessages/Resources/warningIcon@3x.png"; sourceTree = ""; };
+ 007ACA6F89C6C856F78352A086F3B8EA /* CornerRoundingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CornerRoundingView.swift; path = SwiftMessages/CornerRoundingView.swift; sourceTree = ""; };
+ 0201BC51C7CA061016B619400691A139 /* AccessibleMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AccessibleMessage.swift; path = SwiftMessages/AccessibleMessage.swift; sourceTree = ""; };
093D5BBE2A96A1A7AC0432A3AB933576 /* Pods-iMessageDemo-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-iMessageDemo-Info.plist"; sourceTree = ""; };
- 0970322A5DD8B4A8373C35ED051DE156 /* NSLayoutConstraint+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSLayoutConstraint+Extensions.swift"; path = "SwiftMessages/NSLayoutConstraint+Extensions.swift"; sourceTree = ""; };
- 0A8566413BFA3FE6827E63E30515C9B3 /* WindowViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WindowViewController.swift; path = SwiftMessages/WindowViewController.swift; sourceTree = ""; };
- 0B3A169D83BDA3613A661845D1607FC0 /* successIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconSubtle@2x.png"; path = "SwiftMessages/Resources/successIconSubtle@2x.png"; sourceTree = ""; };
+ 0AF65ECDAFAD03A79B5571C6F66D8F35 /* TopBottomAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TopBottomAnimation.swift; path = SwiftMessages/TopBottomAnimation.swift; sourceTree = ""; };
+ 0BEC185781E869FB5FDB7F10538230C7 /* SwiftMessages.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftMessages.modulemap; sourceTree = ""; };
+ 0D2B448BE319CF56A38E222C0B7DF4CB /* PhysicsAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PhysicsAnimation.swift; path = SwiftMessages/PhysicsAnimation.swift; sourceTree = ""; };
1341BB7116EC50FDF7062C6A91DEDF49 /* Pods-iMessageExtensionDemo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-iMessageExtensionDemo-acknowledgements.plist"; sourceTree = ""; };
+ 141AADF8046C9D5EC8E194DF662BAC41 /* ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist"; sourceTree = ""; };
14BF989232A1D55A0FDAAB70B5A8E1BF /* Pods-iMessageDemo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-iMessageDemo-dummy.m"; sourceTree = ""; };
- 15C4C88778A19C193D1EC77FA77BAE4C /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIViewController+Extensions.swift"; path = "SwiftMessages/UIViewController+Extensions.swift"; sourceTree = ""; };
- 19B5EF40CEC1F6DB23F428DC159D4BC2 /* CALayer+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CALayer+Extensions.swift"; path = "SwiftMessages/CALayer+Extensions.swift"; sourceTree = ""; };
- 1B04615682E8B787C964824435BC6616 /* errorIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconLight@2x.png"; path = "SwiftMessages/Resources/errorIconLight@2x.png"; sourceTree = ""; };
- 1DC54BB09EFDFEDE11F484FE73BEDC60 /* successIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIconSubtle.png; path = SwiftMessages/Resources/successIconSubtle.png; sourceTree = ""; };
- 2337E6D5F621F3CE9A1E3761984EBE87 /* PhysicsPanHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PhysicsPanHandler.swift; path = SwiftMessages/PhysicsPanHandler.swift; sourceTree = ""; };
- 267E35F9851AAE50DFB8FA0DCA7F2980 /* Animator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Animator.swift; path = SwiftMessages/Animator.swift; sourceTree = ""; };
- 2B6B36CBE6DC07B2F005E30EA2B121CB /* LICENSE.md */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.md; sourceTree = ""; };
- 2B7213B7DC5432DA2B272F25E17AA364 /* infoIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconSubtle@3x.png"; path = "SwiftMessages/Resources/infoIconSubtle@3x.png"; sourceTree = ""; };
- 2CFBBC25592C97C925B6F81B53BE57CB /* warningIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIcon@3x.png"; path = "SwiftMessages/Resources/warningIcon@3x.png"; sourceTree = ""; };
+ 17ADABD24F805C5F7FF62167E7ABEF0A /* successIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconSubtle@3x.png"; path = "SwiftMessages/Resources/successIconSubtle@3x.png"; sourceTree = ""; };
+ 1A331C2E0BE2AE2118D65AA1F12519F2 /* PassthroughWindow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughWindow.swift; path = SwiftMessages/PassthroughWindow.swift; sourceTree = ""; };
+ 1E2FE4DB6869F330F19A3A5459AAFFFB /* StatusLine.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = StatusLine.xib; path = SwiftMessages/Resources/StatusLine.xib; sourceTree = ""; };
+ 1ED635B9451869879B1A404F00C3CCC7 /* SwiftMessages-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftMessages-prefix.pch"; sourceTree = ""; };
+ 24021DCE87BE9746D1DFB436C0A3AF7A /* Theme.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Theme.swift; path = SwiftMessages/Theme.swift; sourceTree = ""; };
+ 29A39558830996C4F54686A1748B74B1 /* warningIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIcon@2x.png"; path = "SwiftMessages/Resources/warningIcon@2x.png"; sourceTree = ""; };
2D0ECE831FB5E0EE1D68E837671320C7 /* Pods-iMessageDemo-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-iMessageDemo-umbrella.h"; sourceTree = ""; };
- 2E6941E59EF0D89949E3DF3D89488430 /* Weak.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Weak.swift; path = SwiftMessages/Weak.swift; sourceTree = ""; };
- 337B3108412E3812254B85BCC4F90EB8 /* infoIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIcon@3x.png"; path = "SwiftMessages/Resources/infoIcon@3x.png"; sourceTree = ""; };
- 346718C2C7A108C86535F89FEB0EC176 /* SwiftMessages.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftMessages.modulemap; sourceTree = ""; };
- 382E6375390EBB09F829519F8ACCB7D7 /* PassthroughWindow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughWindow.swift; path = SwiftMessages/PassthroughWindow.swift; sourceTree = ""; };
- 396FCF260E9C2B3F11080A91E3D72334 /* TopBottomAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TopBottomAnimation.swift; path = SwiftMessages/TopBottomAnimation.swift; sourceTree = ""; };
- 397C8F928170138667B9326F9655D75D /* UIWindow+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIWindow+Extensions.swift"; path = "SwiftMessages/UIWindow+Extensions.swift"; sourceTree = ""; };
- 3C313FB1D33EF4B477FD5D3D6179A8BE /* errorIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconSubtle@2x.png"; path = "SwiftMessages/Resources/errorIconSubtle@2x.png"; sourceTree = ""; };
- 3DF091E68C4659506DB08B0876BD274C /* CenteredView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = CenteredView.xib; path = SwiftMessages/Resources/CenteredView.xib; sourceTree = ""; };
- 42F1E753E61B6EDED3908AC66994649C /* CardView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = CardView.xib; path = SwiftMessages/Resources/CardView.xib; sourceTree = ""; };
- 4412F313361EFEE7A0193533A5AC5999 /* infoIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconLight@3x.png"; path = "SwiftMessages/Resources/infoIconLight@3x.png"; sourceTree = ""; };
- 4512DEEA328AB0AAA95D77C84C89E02C /* warningIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIconSubtle.png; path = SwiftMessages/Resources/warningIconSubtle.png; sourceTree = ""; };
- 453BC098B6A052020C40DE576F684C7B /* errorIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconSubtle@3x.png"; path = "SwiftMessages/Resources/errorIconSubtle@3x.png"; sourceTree = ""; };
+ 3259F99D03B6D738D7F47A625E7BD3BE /* warningIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIcon.png; path = SwiftMessages/Resources/warningIcon.png; sourceTree = ""; };
+ 36F7B24601DF4C00B14EC8CE2D4A48DC /* UIEdgeInsets+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIEdgeInsets+Extensions.swift"; path = "SwiftMessages/UIEdgeInsets+Extensions.swift"; sourceTree = ""; };
+ 3E2EB968B30DE56F38B5FCFFEDE9F88F /* NSBundle+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSBundle+Extensions.swift"; path = "SwiftMessages/NSBundle+Extensions.swift"; sourceTree = ""; };
+ 45844D489A130BA91E91E7CDD4969862 /* infoIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconSubtle@2x.png"; path = "SwiftMessages/Resources/infoIconSubtle@2x.png"; sourceTree = ""; };
+ 467EAD44C7F625F384822180F004E64F /* CALayer+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CALayer+Extensions.swift"; path = "SwiftMessages/CALayer+Extensions.swift"; sourceTree = ""; };
+ 468D9889455DE51BD5BBC2360BDBB877 /* errorIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconSubtle@2x.png"; path = "SwiftMessages/Resources/errorIconSubtle@2x.png"; sourceTree = ""; };
4824F23D80FF9070A5F8A452DB11EB9A /* SwiftMessages.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftMessages.framework; path = SwiftMessages.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 4F8D7902822221456B697BB41111E450 /* CornerRoundingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CornerRoundingView.swift; path = SwiftMessages/CornerRoundingView.swift; sourceTree = ""; };
- 4FE466AC4123CDAE9FDA9FCF4FB9CC60 /* infoIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconSubtle@2x.png"; path = "SwiftMessages/Resources/infoIconSubtle@2x.png"; sourceTree = ""; };
- 536660614870EA0E051BF6BDDF495798 /* KeyboardTrackingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KeyboardTrackingView.swift; path = SwiftMessages/KeyboardTrackingView.swift; sourceTree = ""; };
- 54B278C80D821C120FA70ABB6CAF1F46 /* successIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconSubtle@3x.png"; path = "SwiftMessages/Resources/successIconSubtle@3x.png"; sourceTree = ""; };
- 5C0DE01AB7D0935933E7AFBDF2945814 /* Identifiable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Identifiable.swift; path = SwiftMessages/Identifiable.swift; sourceTree = ""; };
+ 48DC3BADDA3A20F2AEB8585117DAFA0D /* infoIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIcon@3x.png"; path = "SwiftMessages/Resources/infoIcon@3x.png"; sourceTree = ""; };
+ 4D34E3F2A49E9024A96334DA4147F27B /* errorIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconLight@3x.png"; path = "SwiftMessages/Resources/errorIconLight@3x.png"; sourceTree = ""; };
+ 52F1CA85E0EED7D94FE0036BC92EB3EC /* successIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIconLight.png; path = SwiftMessages/Resources/successIconLight.png; sourceTree = ""; };
+ 59FEAC25BE3FCB9F8373DE26400CC89D /* SwiftMessages.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = SwiftMessages.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
+ 5A16E25077F8D76288BE678E6AC1C884 /* SwiftMessages.Config+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SwiftMessages.Config+Extensions.swift"; path = "SwiftMessages/SwiftMessages.Config+Extensions.swift"; sourceTree = ""; };
5CAB201AD00CAB811B045E2FFB5C03A8 /* Pods-iMessageExtensionDemo-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-iMessageExtensionDemo-umbrella.h"; sourceTree = ""; };
- 60268FE48AA4DC9FD5060B1E5CE68453 /* errorIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIcon@2x.png"; path = "SwiftMessages/Resources/errorIcon@2x.png"; sourceTree = ""; };
- 62755A788F910CA88887B6F63BBC545F /* successIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIcon@2x.png"; path = "SwiftMessages/Resources/successIcon@2x.png"; sourceTree = ""; };
6489B2A759075E9DC1D1406734F45B5F /* Pods-iMessageExtensionDemo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-iMessageExtensionDemo.modulemap"; sourceTree = ""; };
- 6516EE9BFCB9C53C151359F9D0247562 /* infoIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconLight@2x.png"; path = "SwiftMessages/Resources/infoIconLight@2x.png"; sourceTree = ""; };
- 667DECE93ABCC6869A071FFEB0F83EA5 /* warningIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconSubtle@3x.png"; path = "SwiftMessages/Resources/warningIconSubtle@3x.png"; sourceTree = ""; };
- 6E9D4A0FDDEEDDC5A1A63D89B43C1F18 /* SwiftMessages.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftMessages.debug.xcconfig; sourceTree = ""; };
- 70E7AB099F856140EF93D5B94A967418 /* infoIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = infoIcon.png; path = SwiftMessages/Resources/infoIcon.png; sourceTree = ""; };
- 7241B2130D211F0832CCE4928CBB6486 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; };
- 72A865FFBAE49EF66A35CB9D709E8D7E /* successIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconLight@3x.png"; path = "SwiftMessages/Resources/successIconLight@3x.png"; sourceTree = ""; };
- 79E38069364BC5DF4EA88F352E28B242 /* warningIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIconLight.png; path = SwiftMessages/Resources/warningIconLight.png; sourceTree = ""; };
- 7A6801849037A728E9BC50E06CE8AD2F /* StatusLine.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = StatusLine.xib; path = SwiftMessages/Resources/StatusLine.xib; sourceTree = ""; };
- 7A965DD26246DCA8CE39FBAB348ABA24 /* Presenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Presenter.swift; path = SwiftMessages/Presenter.swift; sourceTree = ""; };
+ 676F359BE8561CF7512DB8B42CD7873A /* infoIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconLight@3x.png"; path = "SwiftMessages/Resources/infoIconLight@3x.png"; sourceTree = ""; };
+ 705B5AF043D00B6538599B4EB1ECD77C /* CardView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = CardView.xib; path = SwiftMessages/Resources/CardView.xib; sourceTree = ""; };
+ 7100245A2722BD53D5B3927ED649069F /* errorIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = errorIconLight.png; path = SwiftMessages/Resources/errorIconLight.png; sourceTree = ""; };
+ 730840765E737D45772EBE66DB8A6D2E /* infoIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = infoIconLight.png; path = SwiftMessages/Resources/infoIconLight.png; sourceTree = ""; };
+ 74C53DDA65E08AD7274EA6625408AB99 /* SwiftMessages-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftMessages-Info.plist"; sourceTree = ""; };
+ 753B78926D6BB175E96AB6E6F3514E87 /* UIWindow+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIWindow+Extensions.swift"; path = "SwiftMessages/UIWindow+Extensions.swift"; sourceTree = ""; };
+ 760BFB41B33B6ED91B3FFD68D39083A0 /* successIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconLight@2x.png"; path = "SwiftMessages/Resources/successIconLight@2x.png"; sourceTree = ""; };
+ 778F6E19CE49B8EDBAC2FCCD8195A55B /* MessageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageView.swift; path = SwiftMessages/MessageView.swift; sourceTree = ""; };
+ 787EE6DA4FBC3BF85ED2CF0BB6EBF494 /* CenteredView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = CenteredView.xib; path = SwiftMessages/Resources/CenteredView.xib; sourceTree = ""; };
+ 79D34B3C6875DA0279CB934C84CD000B /* successIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIcon@2x.png"; path = "SwiftMessages/Resources/successIcon@2x.png"; sourceTree = ""; };
+ 7C4DF53A4B44C246968618BF25962786 /* warningIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconLight@3x.png"; path = "SwiftMessages/Resources/warningIconLight@3x.png"; sourceTree = ""; };
+ 7C8214A441D845A4A4DD6570FD5D458F /* MarginAdjustable+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "MarginAdjustable+Extensions.swift"; path = "SwiftMessages/MarginAdjustable+Extensions.swift"; sourceTree = ""; };
7CC6A596A9C1659D8E93222DA4144414 /* Pods-iMessageExtensionDemo-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-iMessageExtensionDemo-Info.plist"; sourceTree = ""; };
7F40CA14AD738DD186B4DA8FD14AE5BD /* Pods-iMessageExtensionDemo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-iMessageExtensionDemo-dummy.m"; sourceTree = ""; };
- 7FCF161BD9F1C2CAAFBCADE5E59BD3FD /* NSBundle+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSBundle+Extensions.swift"; path = "SwiftMessages/NSBundle+Extensions.swift"; sourceTree = ""; };
820B743874F7AC9F9E3970D68E2E60FA /* Pods-iMessageDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-iMessageDemo.release.xcconfig"; sourceTree = ""; };
- 8341EF04E2B20C2BF6D4AF2240F80A56 /* Error.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Error.swift; path = SwiftMessages/Error.swift; sourceTree = ""; };
- 848251807107C20960A3DABAB27F7475 /* errorIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconLight@3x.png"; path = "SwiftMessages/Resources/errorIconLight@3x.png"; sourceTree = ""; };
- 874D31DE863C88B1D699E1EBFBE0641B /* warningIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconLight@2x.png"; path = "SwiftMessages/Resources/warningIconLight@2x.png"; sourceTree = ""; };
- 8901520225CE89F44E6DE88688F29C10 /* MessageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageView.swift; path = SwiftMessages/MessageView.swift; sourceTree = ""; };
+ 8315EA451FE61625920FEF68174A0D22 /* infoIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconLight@2x.png"; path = "SwiftMessages/Resources/infoIconLight@2x.png"; sourceTree = ""; };
+ 860D833A7A1B108A89ED34AD74778AC0 /* warningIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIconSubtle.png; path = SwiftMessages/Resources/warningIconSubtle.png; sourceTree = ""; };
+ 87745BF2C7154EF88509BED0D71243F1 /* SwiftMessages.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftMessages.debug.xcconfig; sourceTree = ""; };
+ 88D73E42D996B226222A4EBA46F7DC6D /* Weak.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Weak.swift; path = SwiftMessages/Weak.swift; sourceTree = ""; };
+ 8AD355ED684A939F2A4E333F95E8AC31 /* warningIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconSubtle@2x.png"; path = "SwiftMessages/Resources/warningIconSubtle@2x.png"; sourceTree = ""; };
+ 8D219D80184B8ED97808EE17507B213A /* Animator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Animator.swift; path = SwiftMessages/Animator.swift; sourceTree = ""; };
8D54691037F1CA4653B76F0558E2AA82 /* Pods-iMessageExtensionDemo-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-iMessageExtensionDemo-acknowledgements.markdown"; sourceTree = ""; };
- 90F364E0C9A6EFE24680868D0BD293F1 /* SwiftMessages-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftMessages-Info.plist"; sourceTree = ""; };
+ 90AC342C6F09BF7715D4FB95512DD68A /* KeyboardTrackingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KeyboardTrackingView.swift; path = SwiftMessages/KeyboardTrackingView.swift; sourceTree = ""; };
915DE2E4E300BAD440BE13F72E49D731 /* Pods-iMessageDemo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-iMessageDemo-acknowledgements.plist"; sourceTree = ""; };
- 9C110C924ED12D2D32ECC27503018A31 /* infoIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = infoIconLight.png; path = SwiftMessages/Resources/infoIconLight.png; sourceTree = ""; };
- 9CF61FDEFE095F0486E9914F2262ADB9 /* MaskingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MaskingView.swift; path = SwiftMessages/MaskingView.swift; sourceTree = ""; };
- 9D1FEAC04417D847EDC10783E054988F /* errorIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = errorIcon.png; path = SwiftMessages/Resources/errorIcon.png; sourceTree = ""; };
+ 91D9224F29E092950BADC27C979E10CC /* successIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconSubtle@2x.png"; path = "SwiftMessages/Resources/successIconSubtle@2x.png"; sourceTree = ""; };
+ 9C6E00017F9E79F6D4926E9CB43A66DF /* SwiftMessages-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftMessages-dummy.m"; sourceTree = ""; };
+ 9CBEAC9D0EF4113C3FD3B15F511A92D0 /* SwiftMessages-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftMessages-umbrella.h"; sourceTree = ""; };
9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
- A0D0E8B0020635F606875DD02735C502 /* BaseView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseView.swift; path = SwiftMessages/BaseView.swift; sourceTree = ""; };
- A2F9031B7FA82A17F04D4403091DF836 /* SwiftMessages-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftMessages-dummy.m"; sourceTree = ""; };
- A3C32E945AE3E6394EF85CD6BEC714B4 /* SwiftMessages.Config+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SwiftMessages.Config+Extensions.swift"; path = "SwiftMessages/SwiftMessages.Config+Extensions.swift"; sourceTree = ""; };
- A80433B71162112A79043CB64261DB51 /* successIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIconLight.png; path = SwiftMessages/Resources/successIconLight.png; sourceTree = ""; };
- A850F76D7E3FEDC20FFB877454069171 /* errorIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = errorIconSubtle.png; path = SwiftMessages/Resources/errorIconSubtle.png; sourceTree = ""; };
- A9A13E69643D651322647C28E3F9E9C9 /* UIEdgeInsets+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIEdgeInsets+Extensions.swift"; path = "SwiftMessages/UIEdgeInsets+Extensions.swift"; sourceTree = ""; };
- AE62AA801971C530345349D18AFCCB82 /* MessageView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = MessageView.xib; path = SwiftMessages/Resources/MessageView.xib; sourceTree = ""; };
+ A0EE84E98A10805A2D64B836C465ED11 /* warningIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconSubtle@3x.png"; path = "SwiftMessages/Resources/warningIconSubtle@3x.png"; sourceTree = ""; };
+ A342E145FED9CD8DB4F464D110203E7C /* successIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIcon.png; path = SwiftMessages/Resources/successIcon.png; sourceTree = ""; };
AE7AEA9CE6B44DCC96AE4E68FA644DAA /* Pods-iMessageExtensionDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-iMessageExtensionDemo.release.xcconfig"; sourceTree = ""; };
AFC41396FB1BD59C9A69EE1DD82E47C2 /* Pods_iMessageDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_iMessageDemo.framework; path = "Pods-iMessageDemo.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
- AFFDB7DDC6B6B064B9D12281E2531BFA /* SwiftMessagesSegue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftMessagesSegue.swift; path = SwiftMessages/SwiftMessagesSegue.swift; sourceTree = ""; };
- B6DEAADC09FEB1A8D5B90108103EE478 /* errorIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIcon@3x.png"; path = "SwiftMessages/Resources/errorIcon@3x.png"; sourceTree = ""; };
- B7FD0618783A3E6B90D3A3323633959F /* TabView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = TabView.xib; path = SwiftMessages/Resources/TabView.xib; sourceTree = ""; };
- B91AD9D9E743D17D553D48103BE27C46 /* MarginAdjustable+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "MarginAdjustable+Extensions.swift"; path = "SwiftMessages/MarginAdjustable+Extensions.swift"; sourceTree = ""; };
+ B031268635405AA009D05130C0FC253C /* successIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIconSubtle.png; path = SwiftMessages/Resources/successIconSubtle.png; sourceTree = ""; };
+ B7BF853CD0CDFA20423D4C813B34B57F /* SwiftMessages.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftMessages.release.xcconfig; sourceTree = ""; };
+ B8A4CCB4B08D2D3BE586212AB4167DC2 /* MessageView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = MessageView.xib; path = SwiftMessages/Resources/MessageView.xib; sourceTree = ""; };
B99CBDE49D6502CF64EB9059C005BF31 /* Pods-iMessageDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-iMessageDemo.debug.xcconfig"; sourceTree = ""; };
+ BDEF50CAF615897F7A8540579B445634 /* PhysicsPanHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PhysicsPanHandler.swift; path = SwiftMessages/PhysicsPanHandler.swift; sourceTree = ""; };
BEBF018059B0DFCAC8494ABD1C578AD9 /* SwiftMessages_SwiftMessages.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = SwiftMessages_SwiftMessages.bundle; path = "SwiftMessages-SwiftMessages_SwiftMessages.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
+ BF27E3EF103BACDEE8CA842B2C90C8CA /* SwiftMessagesSegue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftMessagesSegue.swift; path = SwiftMessages/SwiftMessagesSegue.swift; sourceTree = ""; };
BF61E78F8E8EE539F4A63C5A9D43AC15 /* Pods-iMessageDemo-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-iMessageDemo-frameworks.sh"; sourceTree = ""; };
- BFEF746702215C33B51BEE64C4E48F0A /* warningIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIcon@2x.png"; path = "SwiftMessages/Resources/warningIcon@2x.png"; sourceTree = ""; };
- C17CFEF9B761A322945F74D86CA88036 /* warningIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconLight@3x.png"; path = "SwiftMessages/Resources/warningIconLight@3x.png"; sourceTree = ""; };
C306ACAFEE157959D78E71DBBBD675DC /* Pods-iMessageExtensionDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-iMessageExtensionDemo.debug.xcconfig"; sourceTree = ""; };
- C3216CF40D770C387D45C3B4AF2CC9E0 /* SwiftMessages.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftMessages.swift; path = SwiftMessages/SwiftMessages.swift; sourceTree = ""; };
- C614EECDDFE644AF0BF7CB16A3D74404 /* SwiftMessages-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftMessages-umbrella.h"; sourceTree = ""; };
- C6C56947CAF8EFCC7858E1E2F1273427 /* MarginAdjustable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MarginAdjustable.swift; path = SwiftMessages/MarginAdjustable.swift; sourceTree = ""; };
- C7FE39695CB7C6997ACA39C8680B414A /* SwiftMessages.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = SwiftMessages.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
- C8155ED78358FA5CF39089176FBDE501 /* successIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIcon@3x.png"; path = "SwiftMessages/Resources/successIcon@3x.png"; sourceTree = ""; };
- C9D915B60769D3C45A0DA3A5BA9514B8 /* ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist"; sourceTree = ""; };
- CAB58A9F688DD39112E6CDF20C8969C0 /* BackgroundViewable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BackgroundViewable.swift; path = SwiftMessages/BackgroundViewable.swift; sourceTree = ""; };
+ C56AB83FDAB8D6A1328E7EECCAD99A69 /* warningIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIconLight.png; path = SwiftMessages/Resources/warningIconLight.png; sourceTree = ""; };
+ C5E610C06F5B006DE57F34D5994532FB /* Error.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Error.swift; path = SwiftMessages/Error.swift; sourceTree = ""; };
+ C706F1F1C6B3CE84445485C8577D5388 /* BackgroundViewable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BackgroundViewable.swift; path = SwiftMessages/BackgroundViewable.swift; sourceTree = ""; };
+ C787DA4E67B952C984FF5B065E0A2FF7 /* errorIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = errorIconSubtle.png; path = SwiftMessages/Resources/errorIconSubtle.png; sourceTree = ""; };
+ C7EE64CFE0084CF5213A03AF29A668ED /* BaseView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseView.swift; path = SwiftMessages/BaseView.swift; sourceTree = ""; };
+ C9F5DBB6D77B1E61E9BB1A722A4E1823 /* infoIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconSubtle@3x.png"; path = "SwiftMessages/Resources/infoIconSubtle@3x.png"; sourceTree = ""; };
CBC3F501D8BC852716D085B3022E68CA /* Pods_iMessageExtensionDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_iMessageExtensionDemo.framework; path = "Pods-iMessageExtensionDemo.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
CC9152C843976F18EF9AE005786DCC80 /* Pods-iMessageDemo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-iMessageDemo.modulemap"; sourceTree = ""; };
+ D032FCFAE6607CF878AA2F35EF93146C /* successIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIcon@3x.png"; path = "SwiftMessages/Resources/successIcon@3x.png"; sourceTree = ""; };
+ D1D69BE188B82D84ED23AC4E27BAB61D /* MaskingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MaskingView.swift; path = SwiftMessages/MaskingView.swift; sourceTree = ""; };
D245E0514AAC1A2B9A6D5EA2F383E90F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
- D5607E285A85AC7163B0B8FD447FD27E /* Theme.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Theme.swift; path = SwiftMessages/Theme.swift; sourceTree = ""; };
- D7C557E1DC95AFA417E94ED01301F9F2 /* PassthroughView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughView.swift; path = SwiftMessages/PassthroughView.swift; sourceTree = ""; };
- E070773539E02C11297794CC4CB839D6 /* SwiftMessages.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftMessages.release.xcconfig; sourceTree = ""; };
+ D261B7BE0088C26BF6744F27B894492A /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIViewController+Extensions.swift"; path = "SwiftMessages/UIViewController+Extensions.swift"; sourceTree = ""; };
+ D30B2BF71F9D2C63C2D202C99827CDC1 /* errorIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconLight@2x.png"; path = "SwiftMessages/Resources/errorIconLight@2x.png"; sourceTree = ""; };
+ D68834C60D0C5EA751E9F12E427C5FFE /* MarginAdjustable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MarginAdjustable.swift; path = SwiftMessages/MarginAdjustable.swift; sourceTree = ""; };
+ D8DEFE9675E5359A46A443182F127F06 /* WindowScene.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WindowScene.swift; path = SwiftMessages/WindowScene.swift; sourceTree = ""; };
+ D9AA0E820F1C1AA219C066370332845A /* WindowViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WindowViewController.swift; path = SwiftMessages/WindowViewController.swift; sourceTree = ""; };
+ DB6924EB5FC7236837637AE8F409000A /* NSLayoutConstraint+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSLayoutConstraint+Extensions.swift"; path = "SwiftMessages/NSLayoutConstraint+Extensions.swift"; sourceTree = ""; };
+ DEC0A6AE07C3285CA508F8FA3F4FE27D /* errorIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = errorIcon.png; path = SwiftMessages/Resources/errorIcon.png; sourceTree = ""; };
+ DF3DE135AB5C5C789CABAECC704CE907 /* errorIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIcon@2x.png"; path = "SwiftMessages/Resources/errorIcon@2x.png"; sourceTree = ""; };
+ E03CBB908F2EC39AA5DA7AF04E1BDDD6 /* PassthroughView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughView.swift; path = SwiftMessages/PassthroughView.swift; sourceTree = ""; };
+ E0E4D99C4F78B9BA011D83FE63EE0946 /* errorIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIcon@3x.png"; path = "SwiftMessages/Resources/errorIcon@3x.png"; sourceTree = ""; };
+ E31D045D9E355D4F7F75564026B2051A /* errorIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconSubtle@3x.png"; path = "SwiftMessages/Resources/errorIconSubtle@3x.png"; sourceTree = ""; };
+ E41BFEB1BFF85793C0DB85F95184B752 /* infoIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = infoIcon.png; path = SwiftMessages/Resources/infoIcon.png; sourceTree = ""; };
E473E4F019E816262A61B7F5E8B42373 /* Pods-iMessageDemo-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-iMessageDemo-acknowledgements.markdown"; sourceTree = ""; };
+ E936107A7CF9821DCBFFAF50D916F1E6 /* infoIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIcon@2x.png"; path = "SwiftMessages/Resources/infoIcon@2x.png"; sourceTree = ""; };
+ E9E929B0E2A84EA903C9923B926A44E2 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; };
EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
- ED86D7B42F55040DCE162653FB3C7EDB /* warningIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconSubtle@2x.png"; path = "SwiftMessages/Resources/warningIconSubtle@2x.png"; sourceTree = ""; };
- EDDAF8A2C45FDDDFD5AFA59203137551 /* AccessibleMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AccessibleMessage.swift; path = SwiftMessages/AccessibleMessage.swift; sourceTree = ""; };
- F7004673F1B51EEC365B32F0E060E564 /* infoIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIcon@2x.png"; path = "SwiftMessages/Resources/infoIcon@2x.png"; sourceTree = ""; };
- F898B2AC5C3404C266BBCA3B6D22B5E4 /* successIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconLight@2x.png"; path = "SwiftMessages/Resources/successIconLight@2x.png"; sourceTree = ""; };
- FC73E6C784AF6CA1F956F57F82ED2803 /* successIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIcon.png; path = SwiftMessages/Resources/successIcon.png; sourceTree = ""; };
- FCDC8870EA94B5B1E966D34D2B1FA5FE /* SwiftMessages-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftMessages-prefix.pch"; sourceTree = ""; };
- FE3BED1799B2F867F5C984C2A051E36A /* PhysicsAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PhysicsAnimation.swift; path = SwiftMessages/PhysicsAnimation.swift; sourceTree = ""; };
+ EABF0CEB87991D02E13306975A8E80BB /* TabView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = TabView.xib; path = SwiftMessages/Resources/TabView.xib; sourceTree = ""; };
+ EC6264350B8D100D5B5C5EEEC316933D /* SwiftMessages.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftMessages.swift; path = SwiftMessages/SwiftMessages.swift; sourceTree = ""; };
+ EFD31968BF9DF7A9E25A136DF254F3A9 /* Identifiable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Identifiable.swift; path = SwiftMessages/Identifiable.swift; sourceTree = ""; };
+ F513F2674553CBC247EE4B24EA25C99C /* Presenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Presenter.swift; path = SwiftMessages/Presenter.swift; sourceTree = ""; };
+ F9CDB54E629D60FF881DF27B949F4C2D /* infoIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = infoIconSubtle.png; path = SwiftMessages/Resources/infoIconSubtle.png; sourceTree = ""; };
+ FA199E6F18AB8900B5400EBA0EB32765 /* successIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconLight@3x.png"; path = "SwiftMessages/Resources/successIconLight@3x.png"; sourceTree = ""; };
+ FC12F21544AE9FE6D9E1E2F7730EF7EC /* LICENSE.md */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.md; sourceTree = ""; };
+ FFB0D50D01FFFA3FC2099E395029AE68 /* warningIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconLight@2x.png"; path = "SwiftMessages/Resources/warningIconLight@2x.png"; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -233,33 +235,112 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- C3AABE927CAF3C6135B4D37CA433F885 /* Frameworks */ = {
+ 9DEA36BAD403380FF5C38B4F2B4C3AB9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
- F2C6C6F4FCF31DEB85ADCA0DE9EF6EEC /* Frameworks */ = {
+ EF08D4F0B96CF6C9AB42DC368EE3849A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- A9EB0C8E49AB748B05CF7941ACAF8475 /* Foundation.framework in Frameworks */,
+ 9DA2F2EED5C99045AF44FF410A012F9D /* Foundation.framework in Frameworks */,
+ ECE268E9A63198F53B3F0337B3EA8AF3 /* UIKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- FA7AA2A57B110DEF3C1F616FA77A05A7 /* Frameworks */ = {
+ F2C6C6F4FCF31DEB85ADCA0DE9EF6EEC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 8148CD8F2B38FB38B7B9CCC12E93ECFB /* Foundation.framework in Frameworks */,
- E88597F65A00A5AF50EEF2ABA2392B2F /* UIKit.framework in Frameworks */,
+ A9EB0C8E49AB748B05CF7941ACAF8475 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 089392E699971024974E80EFFB25EE61 /* AppExtension */ = {
+ isa = PBXGroup;
+ children = (
+ 0201BC51C7CA061016B619400691A139 /* AccessibleMessage.swift */,
+ 8D219D80184B8ED97808EE17507B213A /* Animator.swift */,
+ C706F1F1C6B3CE84445485C8577D5388 /* BackgroundViewable.swift */,
+ C7EE64CFE0084CF5213A03AF29A668ED /* BaseView.swift */,
+ 467EAD44C7F625F384822180F004E64F /* CALayer+Extensions.swift */,
+ 705B5AF043D00B6538599B4EB1ECD77C /* CardView.xib */,
+ 787EE6DA4FBC3BF85ED2CF0BB6EBF494 /* CenteredView.xib */,
+ 007ACA6F89C6C856F78352A086F3B8EA /* CornerRoundingView.swift */,
+ C5E610C06F5B006DE57F34D5994532FB /* Error.swift */,
+ DEC0A6AE07C3285CA508F8FA3F4FE27D /* errorIcon.png */,
+ DF3DE135AB5C5C789CABAECC704CE907 /* errorIcon@2x.png */,
+ E0E4D99C4F78B9BA011D83FE63EE0946 /* errorIcon@3x.png */,
+ 7100245A2722BD53D5B3927ED649069F /* errorIconLight.png */,
+ D30B2BF71F9D2C63C2D202C99827CDC1 /* errorIconLight@2x.png */,
+ 4D34E3F2A49E9024A96334DA4147F27B /* errorIconLight@3x.png */,
+ C787DA4E67B952C984FF5B065E0A2FF7 /* errorIconSubtle.png */,
+ 468D9889455DE51BD5BBC2360BDBB877 /* errorIconSubtle@2x.png */,
+ E31D045D9E355D4F7F75564026B2051A /* errorIconSubtle@3x.png */,
+ EFD31968BF9DF7A9E25A136DF254F3A9 /* Identifiable.swift */,
+ E41BFEB1BFF85793C0DB85F95184B752 /* infoIcon.png */,
+ E936107A7CF9821DCBFFAF50D916F1E6 /* infoIcon@2x.png */,
+ 48DC3BADDA3A20F2AEB8585117DAFA0D /* infoIcon@3x.png */,
+ 730840765E737D45772EBE66DB8A6D2E /* infoIconLight.png */,
+ 8315EA451FE61625920FEF68174A0D22 /* infoIconLight@2x.png */,
+ 676F359BE8561CF7512DB8B42CD7873A /* infoIconLight@3x.png */,
+ F9CDB54E629D60FF881DF27B949F4C2D /* infoIconSubtle.png */,
+ 45844D489A130BA91E91E7CDD4969862 /* infoIconSubtle@2x.png */,
+ C9F5DBB6D77B1E61E9BB1A722A4E1823 /* infoIconSubtle@3x.png */,
+ 90AC342C6F09BF7715D4FB95512DD68A /* KeyboardTrackingView.swift */,
+ D68834C60D0C5EA751E9F12E427C5FFE /* MarginAdjustable.swift */,
+ 7C8214A441D845A4A4DD6570FD5D458F /* MarginAdjustable+Extensions.swift */,
+ D1D69BE188B82D84ED23AC4E27BAB61D /* MaskingView.swift */,
+ 778F6E19CE49B8EDBAC2FCCD8195A55B /* MessageView.swift */,
+ B8A4CCB4B08D2D3BE586212AB4167DC2 /* MessageView.xib */,
+ 3E2EB968B30DE56F38B5FCFFEDE9F88F /* NSBundle+Extensions.swift */,
+ DB6924EB5FC7236837637AE8F409000A /* NSLayoutConstraint+Extensions.swift */,
+ E03CBB908F2EC39AA5DA7AF04E1BDDD6 /* PassthroughView.swift */,
+ 1A331C2E0BE2AE2118D65AA1F12519F2 /* PassthroughWindow.swift */,
+ 0D2B448BE319CF56A38E222C0B7DF4CB /* PhysicsAnimation.swift */,
+ BDEF50CAF615897F7A8540579B445634 /* PhysicsPanHandler.swift */,
+ F513F2674553CBC247EE4B24EA25C99C /* Presenter.swift */,
+ 1E2FE4DB6869F330F19A3A5459AAFFFB /* StatusLine.xib */,
+ A342E145FED9CD8DB4F464D110203E7C /* successIcon.png */,
+ 79D34B3C6875DA0279CB934C84CD000B /* successIcon@2x.png */,
+ D032FCFAE6607CF878AA2F35EF93146C /* successIcon@3x.png */,
+ 52F1CA85E0EED7D94FE0036BC92EB3EC /* successIconLight.png */,
+ 760BFB41B33B6ED91B3FFD68D39083A0 /* successIconLight@2x.png */,
+ FA199E6F18AB8900B5400EBA0EB32765 /* successIconLight@3x.png */,
+ B031268635405AA009D05130C0FC253C /* successIconSubtle.png */,
+ 91D9224F29E092950BADC27C979E10CC /* successIconSubtle@2x.png */,
+ 17ADABD24F805C5F7FF62167E7ABEF0A /* successIconSubtle@3x.png */,
+ EC6264350B8D100D5B5C5EEEC316933D /* SwiftMessages.swift */,
+ 5A16E25077F8D76288BE678E6AC1C884 /* SwiftMessages.Config+Extensions.swift */,
+ BF27E3EF103BACDEE8CA842B2C90C8CA /* SwiftMessagesSegue.swift */,
+ EABF0CEB87991D02E13306975A8E80BB /* TabView.xib */,
+ 24021DCE87BE9746D1DFB436C0A3AF7A /* Theme.swift */,
+ 0AF65ECDAFAD03A79B5571C6F66D8F35 /* TopBottomAnimation.swift */,
+ 36F7B24601DF4C00B14EC8CE2D4A48DC /* UIEdgeInsets+Extensions.swift */,
+ D261B7BE0088C26BF6744F27B894492A /* UIViewController+Extensions.swift */,
+ 753B78926D6BB175E96AB6E6F3514E87 /* UIWindow+Extensions.swift */,
+ 3259F99D03B6D738D7F47A625E7BD3BE /* warningIcon.png */,
+ 29A39558830996C4F54686A1748B74B1 /* warningIcon@2x.png */,
+ 0038C9A582787F9882258E8D1080EACF /* warningIcon@3x.png */,
+ C56AB83FDAB8D6A1328E7EECCAD99A69 /* warningIconLight.png */,
+ FFB0D50D01FFFA3FC2099E395029AE68 /* warningIconLight@2x.png */,
+ 7C4DF53A4B44C246968618BF25962786 /* warningIconLight@3x.png */,
+ 860D833A7A1B108A89ED34AD74778AC0 /* warningIconSubtle.png */,
+ 8AD355ED684A939F2A4E333F95E8AC31 /* warningIconSubtle@2x.png */,
+ A0EE84E98A10805A2D64B836C465ED11 /* warningIconSubtle@3x.png */,
+ 88D73E42D996B226222A4EBA46F7DC6D /* Weak.swift */,
+ D8DEFE9675E5359A46A443182F127F06 /* WindowScene.swift */,
+ D9AA0E820F1C1AA219C066370332845A /* WindowViewController.swift */,
+ );
+ name = AppExtension;
+ sourceTree = "";
+ };
1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -288,24 +369,40 @@
name = iOS;
sourceTree = "";
};
- 8F3CF4AFB0CA47B3BFE1C68E51CDF0A9 /* Targets Support Files */ = {
+ 5EAB54907DABB41DF2E9177067EF69D4 /* SwiftMessages */ = {
isa = PBXGroup;
children = (
- 9A912CA1E54EADE1787311C1DF7E8F2E /* Pods-iMessageDemo */,
- BD13800F87C70DC802DBC0C37E8C5E99 /* Pods-iMessageExtensionDemo */,
+ 089392E699971024974E80EFFB25EE61 /* AppExtension */,
+ E7706B1F04CCC75F42C733B60ED5FBDC /* Pod */,
+ 7C00C98D65B96C8BDE003F39DAFBBBDE /* Support Files */,
);
- name = "Targets Support Files";
+ name = SwiftMessages;
+ path = ../..;
sourceTree = "";
};
- 9A632FB0C8554E0688B34926AF9C52DB /* SwiftMessages */ = {
+ 7C00C98D65B96C8BDE003F39DAFBBBDE /* Support Files */ = {
isa = PBXGroup;
children = (
- AD776BCEA093D43499821A6E4251BF03 /* AppExtension */,
- A58DF9B1678B5C3CCA8A840C72186044 /* Pod */,
- B3699CF01F28F4B75166BA983453EAF3 /* Support Files */,
+ 141AADF8046C9D5EC8E194DF662BAC41 /* ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist */,
+ 0BEC185781E869FB5FDB7F10538230C7 /* SwiftMessages.modulemap */,
+ 9C6E00017F9E79F6D4926E9CB43A66DF /* SwiftMessages-dummy.m */,
+ 74C53DDA65E08AD7274EA6625408AB99 /* SwiftMessages-Info.plist */,
+ 1ED635B9451869879B1A404F00C3CCC7 /* SwiftMessages-prefix.pch */,
+ 9CBEAC9D0EF4113C3FD3B15F511A92D0 /* SwiftMessages-umbrella.h */,
+ 87745BF2C7154EF88509BED0D71243F1 /* SwiftMessages.debug.xcconfig */,
+ B7BF853CD0CDFA20423D4C813B34B57F /* SwiftMessages.release.xcconfig */,
);
- name = SwiftMessages;
- path = ../..;
+ name = "Support Files";
+ path = "iMessageDemo/Pods/Target Support Files/SwiftMessages";
+ sourceTree = "";
+ };
+ 8F3CF4AFB0CA47B3BFE1C68E51CDF0A9 /* Targets Support Files */ = {
+ isa = PBXGroup;
+ children = (
+ 9A912CA1E54EADE1787311C1DF7E8F2E /* Pods-iMessageDemo */,
+ BD13800F87C70DC802DBC0C37E8C5E99 /* Pods-iMessageExtensionDemo */,
+ );
+ name = "Targets Support Files";
sourceTree = "";
};
9A912CA1E54EADE1787311C1DF7E8F2E /* Pods-iMessageDemo */ = {
@@ -325,110 +422,6 @@
path = "Target Support Files/Pods-iMessageDemo";
sourceTree = "";
};
- A58DF9B1678B5C3CCA8A840C72186044 /* Pod */ = {
- isa = PBXGroup;
- children = (
- 2B6B36CBE6DC07B2F005E30EA2B121CB /* LICENSE.md */,
- 7241B2130D211F0832CCE4928CBB6486 /* README.md */,
- C7FE39695CB7C6997ACA39C8680B414A /* SwiftMessages.podspec */,
- );
- name = Pod;
- sourceTree = "";
- };
- AD776BCEA093D43499821A6E4251BF03 /* AppExtension */ = {
- isa = PBXGroup;
- children = (
- EDDAF8A2C45FDDDFD5AFA59203137551 /* AccessibleMessage.swift */,
- 267E35F9851AAE50DFB8FA0DCA7F2980 /* Animator.swift */,
- CAB58A9F688DD39112E6CDF20C8969C0 /* BackgroundViewable.swift */,
- A0D0E8B0020635F606875DD02735C502 /* BaseView.swift */,
- 19B5EF40CEC1F6DB23F428DC159D4BC2 /* CALayer+Extensions.swift */,
- 42F1E753E61B6EDED3908AC66994649C /* CardView.xib */,
- 3DF091E68C4659506DB08B0876BD274C /* CenteredView.xib */,
- 4F8D7902822221456B697BB41111E450 /* CornerRoundingView.swift */,
- 8341EF04E2B20C2BF6D4AF2240F80A56 /* Error.swift */,
- 9D1FEAC04417D847EDC10783E054988F /* errorIcon.png */,
- 60268FE48AA4DC9FD5060B1E5CE68453 /* errorIcon@2x.png */,
- B6DEAADC09FEB1A8D5B90108103EE478 /* errorIcon@3x.png */,
- 0892E032AE12339D1AD84BDCC78A3C07 /* errorIconLight.png */,
- 1B04615682E8B787C964824435BC6616 /* errorIconLight@2x.png */,
- 848251807107C20960A3DABAB27F7475 /* errorIconLight@3x.png */,
- A850F76D7E3FEDC20FFB877454069171 /* errorIconSubtle.png */,
- 3C313FB1D33EF4B477FD5D3D6179A8BE /* errorIconSubtle@2x.png */,
- 453BC098B6A052020C40DE576F684C7B /* errorIconSubtle@3x.png */,
- 5C0DE01AB7D0935933E7AFBDF2945814 /* Identifiable.swift */,
- 70E7AB099F856140EF93D5B94A967418 /* infoIcon.png */,
- F7004673F1B51EEC365B32F0E060E564 /* infoIcon@2x.png */,
- 337B3108412E3812254B85BCC4F90EB8 /* infoIcon@3x.png */,
- 9C110C924ED12D2D32ECC27503018A31 /* infoIconLight.png */,
- 6516EE9BFCB9C53C151359F9D0247562 /* infoIconLight@2x.png */,
- 4412F313361EFEE7A0193533A5AC5999 /* infoIconLight@3x.png */,
- 06F2F626BE8417F1806CC5B17F210C90 /* infoIconSubtle.png */,
- 4FE466AC4123CDAE9FDA9FCF4FB9CC60 /* infoIconSubtle@2x.png */,
- 2B7213B7DC5432DA2B272F25E17AA364 /* infoIconSubtle@3x.png */,
- 536660614870EA0E051BF6BDDF495798 /* KeyboardTrackingView.swift */,
- C6C56947CAF8EFCC7858E1E2F1273427 /* MarginAdjustable.swift */,
- B91AD9D9E743D17D553D48103BE27C46 /* MarginAdjustable+Extensions.swift */,
- 9CF61FDEFE095F0486E9914F2262ADB9 /* MaskingView.swift */,
- 8901520225CE89F44E6DE88688F29C10 /* MessageView.swift */,
- AE62AA801971C530345349D18AFCCB82 /* MessageView.xib */,
- 7FCF161BD9F1C2CAAFBCADE5E59BD3FD /* NSBundle+Extensions.swift */,
- 0970322A5DD8B4A8373C35ED051DE156 /* NSLayoutConstraint+Extensions.swift */,
- D7C557E1DC95AFA417E94ED01301F9F2 /* PassthroughView.swift */,
- 382E6375390EBB09F829519F8ACCB7D7 /* PassthroughWindow.swift */,
- FE3BED1799B2F867F5C984C2A051E36A /* PhysicsAnimation.swift */,
- 2337E6D5F621F3CE9A1E3761984EBE87 /* PhysicsPanHandler.swift */,
- 7A965DD26246DCA8CE39FBAB348ABA24 /* Presenter.swift */,
- 7A6801849037A728E9BC50E06CE8AD2F /* StatusLine.xib */,
- FC73E6C784AF6CA1F956F57F82ED2803 /* successIcon.png */,
- 62755A788F910CA88887B6F63BBC545F /* successIcon@2x.png */,
- C8155ED78358FA5CF39089176FBDE501 /* successIcon@3x.png */,
- A80433B71162112A79043CB64261DB51 /* successIconLight.png */,
- F898B2AC5C3404C266BBCA3B6D22B5E4 /* successIconLight@2x.png */,
- 72A865FFBAE49EF66A35CB9D709E8D7E /* successIconLight@3x.png */,
- 1DC54BB09EFDFEDE11F484FE73BEDC60 /* successIconSubtle.png */,
- 0B3A169D83BDA3613A661845D1607FC0 /* successIconSubtle@2x.png */,
- 54B278C80D821C120FA70ABB6CAF1F46 /* successIconSubtle@3x.png */,
- C3216CF40D770C387D45C3B4AF2CC9E0 /* SwiftMessages.swift */,
- A3C32E945AE3E6394EF85CD6BEC714B4 /* SwiftMessages.Config+Extensions.swift */,
- AFFDB7DDC6B6B064B9D12281E2531BFA /* SwiftMessagesSegue.swift */,
- B7FD0618783A3E6B90D3A3323633959F /* TabView.xib */,
- D5607E285A85AC7163B0B8FD447FD27E /* Theme.swift */,
- 396FCF260E9C2B3F11080A91E3D72334 /* TopBottomAnimation.swift */,
- A9A13E69643D651322647C28E3F9E9C9 /* UIEdgeInsets+Extensions.swift */,
- 15C4C88778A19C193D1EC77FA77BAE4C /* UIViewController+Extensions.swift */,
- 397C8F928170138667B9326F9655D75D /* UIWindow+Extensions.swift */,
- 0259757860B26C6072E2640B84EC6D45 /* warningIcon.png */,
- BFEF746702215C33B51BEE64C4E48F0A /* warningIcon@2x.png */,
- 2CFBBC25592C97C925B6F81B53BE57CB /* warningIcon@3x.png */,
- 79E38069364BC5DF4EA88F352E28B242 /* warningIconLight.png */,
- 874D31DE863C88B1D699E1EBFBE0641B /* warningIconLight@2x.png */,
- C17CFEF9B761A322945F74D86CA88036 /* warningIconLight@3x.png */,
- 4512DEEA328AB0AAA95D77C84C89E02C /* warningIconSubtle.png */,
- ED86D7B42F55040DCE162653FB3C7EDB /* warningIconSubtle@2x.png */,
- 667DECE93ABCC6869A071FFEB0F83EA5 /* warningIconSubtle@3x.png */,
- 2E6941E59EF0D89949E3DF3D89488430 /* Weak.swift */,
- 0A8566413BFA3FE6827E63E30515C9B3 /* WindowViewController.swift */,
- );
- name = AppExtension;
- sourceTree = "";
- };
- B3699CF01F28F4B75166BA983453EAF3 /* Support Files */ = {
- isa = PBXGroup;
- children = (
- C9D915B60769D3C45A0DA3A5BA9514B8 /* ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist */,
- 346718C2C7A108C86535F89FEB0EC176 /* SwiftMessages.modulemap */,
- A2F9031B7FA82A17F04D4403091DF836 /* SwiftMessages-dummy.m */,
- 90F364E0C9A6EFE24680868D0BD293F1 /* SwiftMessages-Info.plist */,
- FCDC8870EA94B5B1E966D34D2B1FA5FE /* SwiftMessages-prefix.pch */,
- C614EECDDFE644AF0BF7CB16A3D74404 /* SwiftMessages-umbrella.h */,
- 6E9D4A0FDDEEDDC5A1A63D89B43C1F18 /* SwiftMessages.debug.xcconfig */,
- E070773539E02C11297794CC4CB839D6 /* SwiftMessages.release.xcconfig */,
- );
- name = "Support Files";
- path = "iMessageDemo/Pods/Target Support Files/SwiftMessages";
- sourceTree = "";
- };
BD13800F87C70DC802DBC0C37E8C5E99 /* Pods-iMessageExtensionDemo */ = {
isa = PBXGroup;
children = (
@@ -448,7 +441,7 @@
C5AAA95D48373FAC474F6EFCC1749444 /* Development Pods */ = {
isa = PBXGroup;
children = (
- 9A632FB0C8554E0688B34926AF9C52DB /* SwiftMessages */,
+ 5EAB54907DABB41DF2E9177067EF69D4 /* SwiftMessages */,
);
name = "Development Pods";
sourceTree = "";
@@ -464,30 +457,40 @@
);
sourceTree = "";
};
+ E7706B1F04CCC75F42C733B60ED5FBDC /* Pod */ = {
+ isa = PBXGroup;
+ children = (
+ FC12F21544AE9FE6D9E1E2F7730EF7EC /* LICENSE.md */,
+ E9E929B0E2A84EA903C9923B926A44E2 /* README.md */,
+ 59FEAC25BE3FCB9F8373DE26400CC89D /* SwiftMessages.podspec */,
+ );
+ name = Pod;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
- 96A1C098516CB9F20C4BE19860673FA7 /* Headers */ = {
+ 21076A86F5547DA5AEE656FE5EC63826 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- 560A2B1056FEFE42AC6524A2A1742CA2 /* Pods-iMessageExtensionDemo-umbrella.h in Headers */,
+ AD7F228AE0628DAAE4497493335D2BF7 /* SwiftMessages-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- AEC231A576EA094C9EF913D75BA2D69C /* Headers */ = {
+ 96A1C098516CB9F20C4BE19860673FA7 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- 7BC52E6F0D9D19B05E62E623E53FCE82 /* Pods-iMessageDemo-umbrella.h in Headers */,
+ 560A2B1056FEFE42AC6524A2A1742CA2 /* Pods-iMessageExtensionDemo-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- B534C45C1A426DF58D21D75F281F983A /* Headers */ = {
+ AEC231A576EA094C9EF913D75BA2D69C /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- 9E3D4CA932041E99B6FD56D4E79A726F /* SwiftMessages-umbrella.h in Headers */,
+ 7BC52E6F0D9D19B05E62E623E53FCE82 /* Pods-iMessageDemo-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -496,11 +499,11 @@
/* Begin PBXNativeTarget section */
1FC5E8328653C350899229BDF89FACE5 /* SwiftMessages-SwiftMessages_SwiftMessages */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 57E1F5473FEF9FC2401E805CCF8188C3 /* Build configuration list for PBXNativeTarget "SwiftMessages-SwiftMessages_SwiftMessages" */;
+ buildConfigurationList = 1B3FEB13A547A2F656C2328E0CE130B5 /* Build configuration list for PBXNativeTarget "SwiftMessages-SwiftMessages_SwiftMessages" */;
buildPhases = (
- 5FA15A9B2968910DC30C1AC895A5397A /* Sources */,
- C3AABE927CAF3C6135B4D37CA433F885 /* Frameworks */,
- F8808FE568E0B01931D6216DF79110B1 /* Resources */,
+ FFA9EA2B25A56389D60078D35A7276A6 /* Sources */,
+ 9DEA36BAD403380FF5C38B4F2B4C3AB9 /* Frameworks */,
+ BF76892AD99FBDD7554F3F71E205A3B6 /* Resources */,
);
buildRules = (
);
@@ -523,7 +526,7 @@
buildRules = (
);
dependencies = (
- BB9BD3F204FD8449B62AD70E23DABC13 /* PBXTargetDependency */,
+ 4D52C266BAECF408C5DEB677038E1EEA /* PBXTargetDependency */,
);
name = "Pods-iMessageExtensionDemo";
productName = "Pods-iMessageExtensionDemo";
@@ -532,17 +535,17 @@
};
DAB613A18652334F6BFC5F27BADF515D /* SwiftMessages */ = {
isa = PBXNativeTarget;
- buildConfigurationList = ABCC3636B5EAEBE6D60D155704F40EBC /* Build configuration list for PBXNativeTarget "SwiftMessages" */;
+ buildConfigurationList = 7D9EC6095BF15A96EABE2FE5045DA5DE /* Build configuration list for PBXNativeTarget "SwiftMessages" */;
buildPhases = (
- B534C45C1A426DF58D21D75F281F983A /* Headers */,
- ABE787B29A89D2BB29F92EAE5C8526CF /* Sources */,
- FA7AA2A57B110DEF3C1F616FA77A05A7 /* Frameworks */,
- C69D4A2DC76A80BD6D45A9BE85B2EEB1 /* Resources */,
+ 21076A86F5547DA5AEE656FE5EC63826 /* Headers */,
+ E0A3D02CDE28535DB4F00412E5814A99 /* Sources */,
+ EF08D4F0B96CF6C9AB42DC368EE3849A /* Frameworks */,
+ 036D5B81C59A567C797D02AA3A18D7F4 /* Resources */,
);
buildRules = (
);
dependencies = (
- 03EC5F5CF0CAA96E132B778FB51EBCE9 /* PBXTargetDependency */,
+ 35EE405E4B00027013209FA505020C1C /* PBXTargetDependency */,
);
name = SwiftMessages;
productName = SwiftMessages;
@@ -561,7 +564,7 @@
buildRules = (
);
dependencies = (
- 3CF465B66D2B58FC406E66E621CBCB11 /* PBXTargetDependency */,
+ 50C0F94C8A0A997FF42A574D8367A3C7 /* PBXTargetDependency */,
);
name = "Pods-iMessageDemo";
productName = "Pods-iMessageDemo";
@@ -599,73 +602,73 @@
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
- 61DB2F41473C1B8FEA6385AA240E2586 /* Resources */ = {
+ 036D5B81C59A567C797D02AA3A18D7F4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 47F1E9964F1112D0E8F0FF8C25204E2F /* SwiftMessages_SwiftMessages.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- B1A8F08DE3F2C1EF1D63EF29C9D3D327 /* Resources */ = {
+ 61DB2F41473C1B8FEA6385AA240E2586 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
- C69D4A2DC76A80BD6D45A9BE85B2EEB1 /* Resources */ = {
+ B1A8F08DE3F2C1EF1D63EF29C9D3D327 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 425F2D4CE95436680D77C263FF15221B /* SwiftMessages_SwiftMessages.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- F8808FE568E0B01931D6216DF79110B1 /* Resources */ = {
+ BF76892AD99FBDD7554F3F71E205A3B6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 4E9CCFC43646B6CDBE3B787AB09A0147 /* CardView.xib in Resources */,
- F27E3EEAFDDAA6CB4E7407D6A46DAA5D /* CenteredView.xib in Resources */,
- 5260BD3289BAC54A20457099C4A57EFF /* errorIcon.png in Resources */,
- 683A7897D1E9A73F4717198B1C054D29 /* errorIcon@2x.png in Resources */,
- 6A539682FDDA0E5DA23E1B5F2BA133C1 /* errorIcon@3x.png in Resources */,
- 4E703B2A80C64CF1142872BE31263940 /* errorIconLight.png in Resources */,
- 1F4159921A25C7B2A0E9C587387D829C /* errorIconLight@2x.png in Resources */,
- 4C78ED4E1780F5609E25CE03429C1DE4 /* errorIconLight@3x.png in Resources */,
- 365594AAFDD4EE947EB33E6E86A8578E /* errorIconSubtle.png in Resources */,
- EDA146BF3FF59593677F8B2AA785D8A5 /* errorIconSubtle@2x.png in Resources */,
- D8BDC20F1566606BF64001B6E96B14B6 /* errorIconSubtle@3x.png in Resources */,
- C5FFE932D5EBE2CC8F2ABFEA893D8E9C /* infoIcon.png in Resources */,
- B2CC8FF0F9FF3FE929180CDB32B69F18 /* infoIcon@2x.png in Resources */,
- B60094A8D1343B7351F0EF9C51F2F0DB /* infoIcon@3x.png in Resources */,
- 5720D965B3CE67653082137053FBEC9C /* infoIconLight.png in Resources */,
- D61D59BCDFD2C3C7993CFE883DE60692 /* infoIconLight@2x.png in Resources */,
- 9FFE65CB6E825ECAE4838D53E7BA4C06 /* infoIconLight@3x.png in Resources */,
- C4598A458697C49C961BFDCD090B3A8F /* infoIconSubtle.png in Resources */,
- 2B23A9DFDAACFE9C0AD5EB6899E63475 /* infoIconSubtle@2x.png in Resources */,
- 7ACCA07CCFD868899D61F4B4AE5774DB /* infoIconSubtle@3x.png in Resources */,
- 2558CABB502ED605BC21DCFC55A9C0B7 /* MessageView.xib in Resources */,
- 492F085489FCAB0EEBE74B098F7D3F4D /* StatusLine.xib in Resources */,
- 462CDC24C5C8DD6905C4112B6B4BD2ED /* successIcon.png in Resources */,
- B42A7A38C8014DBDE2632B909F71C355 /* successIcon@2x.png in Resources */,
- 44C0F194D748EE88027414A5B2094E9B /* successIcon@3x.png in Resources */,
- 138A7742F76993FB9EE3555FD2808562 /* successIconLight.png in Resources */,
- BDCF9C5E4F88B2B0AB6D4595E5A281E1 /* successIconLight@2x.png in Resources */,
- 33785D52B8888C2EA02BD0495408E352 /* successIconLight@3x.png in Resources */,
- AC4F13F50EB63B484292D67692BC1F9D /* successIconSubtle.png in Resources */,
- BBFE3BAFFCE67F4EACE0C67A7B7FFC3A /* successIconSubtle@2x.png in Resources */,
- 5DF3F4808ED4A6932839C11A5D742B93 /* successIconSubtle@3x.png in Resources */,
- 57072960EA4F0D307171ED90697D3FAF /* TabView.xib in Resources */,
- 447E8A096C1ABD2E0AC9674E65A827E3 /* warningIcon.png in Resources */,
- BB16D1E73A5D6B27DC4212926986107F /* warningIcon@2x.png in Resources */,
- 64595C731B826EB19E9757D524E0BF76 /* warningIcon@3x.png in Resources */,
- CCF5CC8F6022DFD410DDCC99A90D58B0 /* warningIconLight.png in Resources */,
- 4DB5D1FB08693DDDC32BCF19CC1B1AA0 /* warningIconLight@2x.png in Resources */,
- C6E73F201545CF5ED055C69CD4DB2EFF /* warningIconLight@3x.png in Resources */,
- 1F6162906845BE72A5BCDAF14D6E14B9 /* warningIconSubtle.png in Resources */,
- 89ACEF0F9E524BD21D6C2460FEC375F8 /* warningIconSubtle@2x.png in Resources */,
- 755DA479621A9D2BB8B84540DE648A7A /* warningIconSubtle@3x.png in Resources */,
+ A67A9ADFBCB364FCEF1BD92FF20B285C /* CardView.xib in Resources */,
+ 9F0473806FD530165403E47E834790C2 /* CenteredView.xib in Resources */,
+ 9B1E91097B4BD539EBCBBCC3C62CB75A /* errorIcon.png in Resources */,
+ ADA91E8F5FDCD2EEC3D3B18A5B375C2C /* errorIcon@2x.png in Resources */,
+ A9FFA668A7F81F50FBDCDCE26E891C8B /* errorIcon@3x.png in Resources */,
+ 11DE7052A0A78D6E27D8D129D413DAF6 /* errorIconLight.png in Resources */,
+ 34CB62900FA4AAC84745C7E958657648 /* errorIconLight@2x.png in Resources */,
+ FDC2C20416D7EBF959A461E25FAFB16E /* errorIconLight@3x.png in Resources */,
+ E70A6E572A6DD457A766908E3ADCF49B /* errorIconSubtle.png in Resources */,
+ 668EDAB86421216BEF7D3F932851A834 /* errorIconSubtle@2x.png in Resources */,
+ F69D9D53A5500A42D4B41097537628E5 /* errorIconSubtle@3x.png in Resources */,
+ 8F1BAB73C85D58C56F55E91573C2E7EF /* infoIcon.png in Resources */,
+ ADE48B746D5BB28EC33B403E1E12E0FE /* infoIcon@2x.png in Resources */,
+ 5B9F8D117AF7BEDDB511EF475FA25995 /* infoIcon@3x.png in Resources */,
+ 4B907B48F27F55DF65CC1553C7C26942 /* infoIconLight.png in Resources */,
+ CC9369D0A5F8715733A4D517E45A3B63 /* infoIconLight@2x.png in Resources */,
+ B4D338F85183163DC8CAB8A5864C9015 /* infoIconLight@3x.png in Resources */,
+ 62B05E0AC13A614A2F8D8A1BE9B514B3 /* infoIconSubtle.png in Resources */,
+ 9CFE7FFD7DDE28FCDA72647F2DB82837 /* infoIconSubtle@2x.png in Resources */,
+ C826D41BE5AF283B12C122AEF9640C99 /* infoIconSubtle@3x.png in Resources */,
+ 7B352022AFCAA5C364E1E2F61290628E /* MessageView.xib in Resources */,
+ 30D023ABC2D1CFC829CF04360768B7F8 /* StatusLine.xib in Resources */,
+ 95DD12BBA763163407787AB32AAF8E56 /* successIcon.png in Resources */,
+ C11CE75FD2DFCDF3B72D8D16280A2054 /* successIcon@2x.png in Resources */,
+ 755898E0E511FC5AE881403BEF2A02FC /* successIcon@3x.png in Resources */,
+ 80DE92140CF5AFB5224643FA952EFDEA /* successIconLight.png in Resources */,
+ ADA044C43E517C5F0603B2A0AFB19860 /* successIconLight@2x.png in Resources */,
+ C418A50F3C321227B0C6BE1D793680D4 /* successIconLight@3x.png in Resources */,
+ CD480EEF400EC9B894F3292506BF0179 /* successIconSubtle.png in Resources */,
+ 61548914728141D77F87E31B3911CE7E /* successIconSubtle@2x.png in Resources */,
+ 56F9865D99C4FADB8FC83CA548F82110 /* successIconSubtle@3x.png in Resources */,
+ 9FA48348FB5F41070356A75237367D6D /* TabView.xib in Resources */,
+ DECF1F62709D95EF5B48628A97B3CF98 /* warningIcon.png in Resources */,
+ 946185C05E253C9E47ABCD9EDE7E14D1 /* warningIcon@2x.png in Resources */,
+ B679ED0F79CAF552C081588F3B63B91A /* warningIcon@3x.png in Resources */,
+ 3A8B97D9210D1E2BEED5E1159BE7E748 /* warningIconLight.png in Resources */,
+ E8174481BFB4559462F82062D85C0376 /* warningIconLight@2x.png in Resources */,
+ 4B9459A11E2A1D65AE3224CF468AE8CA /* warningIconLight@3x.png in Resources */,
+ 1662CF43016AFC375200E466F130D90E /* warningIconSubtle.png in Resources */,
+ 6685298EC64F73060F5DB1A841375069 /* warningIconSubtle@2x.png in Resources */,
+ B02B2EAB7B8662AA27D91403BF9AAF36 /* warningIconSubtle@3x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -688,78 +691,79 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 5FA15A9B2968910DC30C1AC895A5397A /* Sources */ = {
+ E0A3D02CDE28535DB4F00412E5814A99 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 02905CCF79B22A773CD0BA32EDB9648A /* AccessibleMessage.swift in Sources */,
+ F75A8D3DA9B4787BEEEBF3F784D5CDEF /* Animator.swift in Sources */,
+ DE23509CED3A1E62F60E7E4BD6D38A35 /* BackgroundViewable.swift in Sources */,
+ 4889E21A2024267A944084FB851200B5 /* BaseView.swift in Sources */,
+ 3BFC9F0FAF0757A2D3574ED4E4100D57 /* CALayer+Extensions.swift in Sources */,
+ 28F2E02536C48A4B661D6D8AAFB5D37E /* CornerRoundingView.swift in Sources */,
+ F9A111F30C3B26D0A35B0829EED70D26 /* Error.swift in Sources */,
+ 4256FC87C833154DCDEE84CD98F910D7 /* Identifiable.swift in Sources */,
+ 13620BA62A66C8C6F9345341BCD111ED /* KeyboardTrackingView.swift in Sources */,
+ 632538BAE98BBFD6CED58844B7611C24 /* MarginAdjustable+Extensions.swift in Sources */,
+ 7905F28CF56E06626475EBA3EB73D905 /* MarginAdjustable.swift in Sources */,
+ 0C55441C4B8356AC1244EED7684E1783 /* MaskingView.swift in Sources */,
+ 934A8FA91D6518CB70273B73F8038ECA /* MessageView.swift in Sources */,
+ F05B5437AFF475FE8811E2A8A734920F /* NSBundle+Extensions.swift in Sources */,
+ B520EDE98BD17CE5676F52A77139A933 /* NSLayoutConstraint+Extensions.swift in Sources */,
+ D34D8255545B84A38C98D2DBB2F12CC5 /* PassthroughView.swift in Sources */,
+ 05D9CBEC9488BAA2962B174703D25218 /* PassthroughWindow.swift in Sources */,
+ FA02B47E32DD9BEAAB8A2D1B66F697D5 /* PhysicsAnimation.swift in Sources */,
+ 9B1F7A4183F57B0AA9DD02624BD8855B /* PhysicsPanHandler.swift in Sources */,
+ F4BE83FBD5001DEDF6736E69ADA6D79B /* Presenter.swift in Sources */,
+ 00764FFD14D83F4ABEC0D4D53D48080A /* SwiftMessages-dummy.m in Sources */,
+ 5CA294C8D3BBC986CF0703D4E2A28687 /* SwiftMessages.Config+Extensions.swift in Sources */,
+ 4E82DE4069FECF20D0E29CB06A0FCFB6 /* SwiftMessages.swift in Sources */,
+ C739607C022819840C267A0B4A7B2FD9 /* SwiftMessagesSegue.swift in Sources */,
+ 9B89868BA12CC4E1D9F116F663E56695 /* Theme.swift in Sources */,
+ 6A933CC66558A1FB0AB0BC76F9807E71 /* TopBottomAnimation.swift in Sources */,
+ 531825CE7041C5C1BA684BDA9C8972A3 /* UIEdgeInsets+Extensions.swift in Sources */,
+ 9DBD1955C7C621D9DCBE03D2161C91A9 /* UIViewController+Extensions.swift in Sources */,
+ 94B459D6CBA2A01D2B8174D138C30920 /* UIWindow+Extensions.swift in Sources */,
+ 926907C8DCE76101AF5CB470DB7797D7 /* Weak.swift in Sources */,
+ AF34F903519AF36E07A90EF1BD703777 /* WindowScene.swift in Sources */,
+ AC0A9B473B11FFF4BDEC0A0598795843 /* WindowViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- ABE787B29A89D2BB29F92EAE5C8526CF /* Sources */ = {
+ FFA9EA2B25A56389D60078D35A7276A6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- A11E7A379B288CCA3AE6785B83FA4316 /* AccessibleMessage.swift in Sources */,
- 44150A4B5B2D251FCBB6CA07DC9872B5 /* Animator.swift in Sources */,
- E94E8711BDDA31B178AA032D3346C307 /* BackgroundViewable.swift in Sources */,
- 4267FACE20717FF3F51C2ACAB8C395A4 /* BaseView.swift in Sources */,
- D49E06426C51C49E9058371138972A69 /* CALayer+Extensions.swift in Sources */,
- 6320AE79D41E8D1F52AF66A670542561 /* CornerRoundingView.swift in Sources */,
- A1734DB0A8A558B2397AF54E63F64416 /* Error.swift in Sources */,
- FCB6832EB4D32EF085E770E8B4A9BC2C /* Identifiable.swift in Sources */,
- 3505AB28DBFA49FBE5C8250F3E067E60 /* KeyboardTrackingView.swift in Sources */,
- 0E7AE1B3CE2734B39ACCE812B4320B44 /* MarginAdjustable+Extensions.swift in Sources */,
- 966B9C1EE6B73E430F03D51A4FD26D20 /* MarginAdjustable.swift in Sources */,
- 5750C24C3A9CAE11C7E36B37434912D0 /* MaskingView.swift in Sources */,
- 0B42A04122166EAD384BCE37FD450FAF /* MessageView.swift in Sources */,
- 461760E2818D72B948B60B4835E7B1ED /* NSBundle+Extensions.swift in Sources */,
- 16047C447B00FAA7F42764EC4167C33B /* NSLayoutConstraint+Extensions.swift in Sources */,
- 0CE00BF7FB0F6376D89B0AFF1CFD7510 /* PassthroughView.swift in Sources */,
- C8F46E0A5853739D3F632B4828FDE9CC /* PassthroughWindow.swift in Sources */,
- 7E5ADF1F3B6849D5A0DF8E2B9C1861C5 /* PhysicsAnimation.swift in Sources */,
- 0303F738260F2C9BAE20B79DE84E82BC /* PhysicsPanHandler.swift in Sources */,
- FF01BC94FADD5A72282AEE043DF523A7 /* Presenter.swift in Sources */,
- FA6CA270F521DF68A75E527954A2DDAD /* SwiftMessages-dummy.m in Sources */,
- F50FE2EE47422AD39AC8F7F115081E7E /* SwiftMessages.Config+Extensions.swift in Sources */,
- B2862C6DDAA6543BB2C8F4541F044564 /* SwiftMessages.swift in Sources */,
- 9CEE0E569456D932AA34329D2038DF98 /* SwiftMessagesSegue.swift in Sources */,
- 2181E713FC7C00EE871FDA6CB62C7E8C /* Theme.swift in Sources */,
- BC4618CE535404A9540D4D110B5767A1 /* TopBottomAnimation.swift in Sources */,
- 52F4ED7F78829270B2AFE5EDBA9EEE2F /* UIEdgeInsets+Extensions.swift in Sources */,
- D9077478C2FCD7C3DD1EBE9373281728 /* UIViewController+Extensions.swift in Sources */,
- 6C7DAA6A68AFDACD67F2C127CEF4DD6F /* UIWindow+Extensions.swift in Sources */,
- 00468531530F8A70E3D83622BD482026 /* Weak.swift in Sources */,
- F5642C087197B9033252FF10FBA92B59 /* WindowViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
- 03EC5F5CF0CAA96E132B778FB51EBCE9 /* PBXTargetDependency */ = {
+ 35EE405E4B00027013209FA505020C1C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "SwiftMessages-SwiftMessages_SwiftMessages";
target = 1FC5E8328653C350899229BDF89FACE5 /* SwiftMessages-SwiftMessages_SwiftMessages */;
- targetProxy = 141E78A8858DBF8B2695DFEDCBDF5158 /* PBXContainerItemProxy */;
+ targetProxy = D19F271ED5B0FED7305E55070B415EDB /* PBXContainerItemProxy */;
};
- 3CF465B66D2B58FC406E66E621CBCB11 /* PBXTargetDependency */ = {
+ 4D52C266BAECF408C5DEB677038E1EEA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = SwiftMessages;
target = DAB613A18652334F6BFC5F27BADF515D /* SwiftMessages */;
- targetProxy = 4DB1DDB02425E67ED85C70C3B138E205 /* PBXContainerItemProxy */;
+ targetProxy = 4B785BB517DA1D687C0B772C77660019 /* PBXContainerItemProxy */;
};
- BB9BD3F204FD8449B62AD70E23DABC13 /* PBXTargetDependency */ = {
+ 50C0F94C8A0A997FF42A574D8367A3C7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = SwiftMessages;
target = DAB613A18652334F6BFC5F27BADF515D /* SwiftMessages */;
- targetProxy = 900F05D1477FFAB64FF410CBB6B9B74D /* PBXContainerItemProxy */;
+ targetProxy = DA9FA5DB745280F35DD4EFAC9A7A4FD7 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
- 24D1D8F3B822E3083FF435C91CB434FD /* Debug */ = {
+ 01CE4E62B8DE70DDCEADD46669F1118B /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 6E9D4A0FDDEEDDC5A1A63D89B43C1F18 /* SwiftMessages.debug.xcconfig */;
+ baseConfigurationReference = 87745BF2C7154EF88509BED0D71243F1 /* SwiftMessages.debug.xcconfig */;
buildSettings = {
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SwiftMessages";
IBSC_MODULE = SwiftMessages;
@@ -773,6 +777,22 @@
};
name = Debug;
};
+ 27EC13F078A5EF4E57265026E5EA01CB /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = B7BF853CD0CDFA20423D4C813B34B57F /* SwiftMessages.release.xcconfig */;
+ buildSettings = {
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SwiftMessages";
+ IBSC_MODULE = SwiftMessages;
+ INFOPLIST_FILE = "Target Support Files/SwiftMessages/ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ PRODUCT_NAME = SwiftMessages_SwiftMessages;
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Release;
+ };
6427804744C4054555383985007A0B6C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -901,40 +921,6 @@
};
name = Release;
};
- 7C5AE2DF0A930DD6AC66390486478632 /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = E070773539E02C11297794CC4CB839D6 /* SwiftMessages.release.xcconfig */;
- buildSettings = {
- "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
- CURRENT_PROJECT_VERSION = 1;
- DEFINES_MODULE = YES;
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
- DYLIB_INSTALL_NAME_BASE = "@rpath";
- GCC_PREFIX_HEADER = "Target Support Files/SwiftMessages/SwiftMessages-prefix.pch";
- INFOPLIST_FILE = "Target Support Files/SwiftMessages/SwiftMessages-Info.plist";
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- "@loader_path/Frameworks",
- );
- MODULEMAP_FILE = "Target Support Files/SwiftMessages/SwiftMessages.modulemap";
- PRODUCT_MODULE_NAME = SwiftMessages;
- PRODUCT_NAME = SwiftMessages;
- SDKROOT = iphoneos;
- SKIP_INSTALL = YES;
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_PREFIX = "";
- };
- name = Release;
- };
891563622FB1DE05CD4905BE16203F07 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C306ACAFEE157959D78E71DBBBD675DC /* Pods-iMessageExtensionDemo.debug.xcconfig */;
@@ -1010,21 +996,38 @@
};
name = Release;
};
- BCFFE899A2E9C1DF0CA120A3F3CECECC /* Release */ = {
+ B9F08B726D3DD8C6ACDBB8CC2E05B693 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = E070773539E02C11297794CC4CB839D6 /* SwiftMessages.release.xcconfig */;
+ baseConfigurationReference = 87745BF2C7154EF88509BED0D71243F1 /* SwiftMessages.debug.xcconfig */;
buildSettings = {
- CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/SwiftMessages";
- IBSC_MODULE = SwiftMessages;
- INFOPLIST_FILE = "Target Support Files/SwiftMessages/ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist";
+ "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+ "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GCC_PREFIX_HEADER = "Target Support Files/SwiftMessages/SwiftMessages-prefix.pch";
+ INFOPLIST_FILE = "Target Support Files/SwiftMessages/SwiftMessages-Info.plist";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- PRODUCT_NAME = SwiftMessages_SwiftMessages;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MODULEMAP_FILE = "Target Support Files/SwiftMessages/SwiftMessages.modulemap";
+ PRODUCT_MODULE_NAME = SwiftMessages;
+ PRODUCT_NAME = SwiftMessages;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
+ SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
- WRAPPER_EXTENSION = bundle;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
};
- name = Release;
+ name = Debug;
};
C9423D1E13393A1A8BC54BE4E87A96AD /* Release */ = {
isa = XCBuildConfiguration;
@@ -1064,9 +1067,9 @@
};
name = Release;
};
- F069CD2F5774D5082336F140E5F68B3A /* Debug */ = {
+ D0E16784196812CD6F00BFEE04C50E82 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 6E9D4A0FDDEEDDC5A1A63D89B43C1F18 /* SwiftMessages.debug.xcconfig */;
+ baseConfigurationReference = B7BF853CD0CDFA20423D4C813B34B57F /* SwiftMessages.release.xcconfig */;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
@@ -1092,10 +1095,11 @@
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
- name = Debug;
+ name = Release;
};
FCA0FCAB93E530D2C6BED8D3910FEB4A /* Debug */ = {
isa = XCBuildConfiguration;
@@ -1137,38 +1141,38 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 20A82A14E31D7EFF5BE9B60529162F4B /* Build configuration list for PBXNativeTarget "Pods-iMessageDemo" */ = {
+ 1B3FEB13A547A2F656C2328E0CE130B5 /* Build configuration list for PBXNativeTarget "SwiftMessages-SwiftMessages_SwiftMessages" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- FCA0FCAB93E530D2C6BED8D3910FEB4A /* Debug */,
- C9423D1E13393A1A8BC54BE4E87A96AD /* Release */,
+ 01CE4E62B8DE70DDCEADD46669F1118B /* Debug */,
+ 27EC13F078A5EF4E57265026E5EA01CB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = {
+ 20A82A14E31D7EFF5BE9B60529162F4B /* Build configuration list for PBXNativeTarget "Pods-iMessageDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 6427804744C4054555383985007A0B6C /* Debug */,
- 74556EDEC03158A3009CA84D67369133 /* Release */,
+ FCA0FCAB93E530D2C6BED8D3910FEB4A /* Debug */,
+ C9423D1E13393A1A8BC54BE4E87A96AD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 57E1F5473FEF9FC2401E805CCF8188C3 /* Build configuration list for PBXNativeTarget "SwiftMessages-SwiftMessages_SwiftMessages" */ = {
+ 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 24D1D8F3B822E3083FF435C91CB434FD /* Debug */,
- BCFFE899A2E9C1DF0CA120A3F3CECECC /* Release */,
+ 6427804744C4054555383985007A0B6C /* Debug */,
+ 74556EDEC03158A3009CA84D67369133 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- ABCC3636B5EAEBE6D60D155704F40EBC /* Build configuration list for PBXNativeTarget "SwiftMessages" */ = {
+ 7D9EC6095BF15A96EABE2FE5045DA5DE /* Build configuration list for PBXNativeTarget "SwiftMessages" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- F069CD2F5774D5082336F140E5F68B3A /* Debug */,
- 7C5AE2DF0A930DD6AC66390486478632 /* Release */,
+ B9F08B726D3DD8C6ACDBB8CC2E05B693 /* Debug */,
+ D0E16784196812CD6F00BFEE04C50E82 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
From 1e49de7b3780b69927bc3e61903d8ec0693a3dc5 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Tue, 5 Oct 2021 13:11:30 -0500
Subject: [PATCH 08/38] Work/9.0.5 (#486)
* Notifify will change before changes are made
* Account for bounceAnimationOffset with keyboard avoidance
* Release prep
---
CHANGELOG.md | 7 +++++++
SwiftMessages.podspec | 2 +-
SwiftMessages/KeyboardTrackingView.swift | 16 +++++++++++++++-
SwiftMessages/MaskingView.swift | 11 ++++++++++-
4 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed08715..de1f84a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,13 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 9.0.5
+
+### Fixes
+
+* #482 Fix timing of `KeyboardTrackingView` callbacks.
+* #483 KeyboardTrackingView causes a small space under bottom-style view
+
## 9.0.4
* #471 Xcode 13 issue - Enum cases with associated values cannot be marked potentially unavailable with '@available'
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index 688f100..c43a529 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '9.0.4'
+ spec.version = '9.0.5'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkick.it' }
diff --git a/SwiftMessages/KeyboardTrackingView.swift b/SwiftMessages/KeyboardTrackingView.swift
index 6af384a..301d969 100644
--- a/SwiftMessages/KeyboardTrackingView.swift
+++ b/SwiftMessages/KeyboardTrackingView.swift
@@ -44,6 +44,18 @@ open class KeyboardTrackingView: UIView {
/// The margin to maintain between the keyboard and the top of the view.
@IBInspectable open var topMargin: CGFloat = 0
+ /// Subclasses can override this to do something before the change.
+ open func willChange(
+ change: KeyboardTrackingView.Change,
+ userInfo: [AnyHashable : Any]
+ ) {}
+
+ /// Subclasses can override this to do something after the change.
+ open func didChange(
+ change: KeyboardTrackingView.Change,
+ userInfo: [AnyHashable : Any]
+ ) {}
+
override public init(frame: CGRect) {
super.init(frame: frame)
postInit()
@@ -101,11 +113,12 @@ open class KeyboardTrackingView: UIView {
guard !(isPaused || isAutomaticallyPaused),
let userInfo = (notification as NSNotification).userInfo,
let value = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
+ willChange(change: change, userInfo: userInfo)
+ delegate?.keyboardTrackingViewWillChange(change: change, userInfo: userInfo)
let keyboardRect = value.cgRectValue
let thisRect = convert(bounds, to: nil)
let newHeight = max(0, thisRect.maxY - keyboardRect.minY) + topMargin
guard heightConstraint.constant != newHeight else { return }
- delegate?.keyboardTrackingViewWillChange(change: change, userInfo: userInfo)
animateKeyboardChange(change: change, height: newHeight, userInfo: userInfo)
}
@@ -115,6 +128,7 @@ open class KeyboardTrackingView: UIView {
let curveNumber = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber {
CATransaction.begin()
CATransaction.setCompletionBlock {
+ self.didChange(change: change, userInfo: userInfo)
self.delegate?.keyboardTrackingViewDidChange(change: change, userInfo: userInfo)
}
UIView.beginAnimations(nil, context: nil)
diff --git a/SwiftMessages/MaskingView.swift b/SwiftMessages/MaskingView.swift
index 0ce4c42..d631342 100644
--- a/SwiftMessages/MaskingView.swift
+++ b/SwiftMessages/MaskingView.swift
@@ -65,6 +65,15 @@ class MaskingView: PassthroughView {
guard let keyboardTrackingView = keyboardTrackingView,
view != keyboardTrackingView,
view != backgroundView else { return }
- keyboardTrackingView.topAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor).with(priority: UILayoutPriority(250)).isActive = true
+ let offset: CGFloat
+ if let adjustable = view as? MarginAdjustable {
+ offset = -adjustable.bounceAnimationOffset
+ } else {
+ offset = 0
+ }
+ keyboardTrackingView.topAnchor.constraint(
+ greaterThanOrEqualTo: view.bottomAnchor,
+ constant: offset
+ ).with(priority: UILayoutPriority(250)).isActive = true
}
}
From b29dd21090b708aa0ae9ecbaf6e2d0487028dc3f Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Fri, 14 Jan 2022 11:33:00 -0600
Subject: [PATCH 09/38] Add view associated type to Event
---
CHANGELOG.md | 7 +++++++
README.md | 4 +++-
SwiftMessages.podspec | 2 +-
SwiftMessages/Presenter.swift | 8 ++++----
SwiftMessages/SwiftMessages.swift | 21 +++++++++++++++++----
5 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de1f84a..8c25038 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,13 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 9.0.6
+
+### Features
+
+* Add `UIView` associated type to `Event`, e.g. `willShow(UIView)` so that event listeners can inspect the view.
+* Add `Event.id: String?` property so that event listeners can reason about the view's ID.
+
## 9.0.5
### Fixes
diff --git a/README.md b/README.md
index c46c84c..97e8374 100644
--- a/README.md
+++ b/README.md
@@ -156,7 +156,9 @@ config.preferredStatusBarStyle = .lightContent
// Specify one or more event listeners to respond to show and hide events.
config.eventListeners.append() { event in
- if case .didHide = event { print("yep") }
+ if case .didHide = event {
+ print("yep id=\(String(describing: event.id)")
+ }
}
SwiftMessages.show(config: config, view: view)
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index c43a529..4c7b945 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '9.0.5'
+ spec.version = '9.0.6'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkick.it' }
diff --git a/SwiftMessages/Presenter.swift b/SwiftMessages/Presenter.swift
index 11243f5..be093be 100644
--- a/SwiftMessages/Presenter.swift
+++ b/SwiftMessages/Presenter.swift
@@ -119,7 +119,7 @@ class Presenter: NSObject {
func show(completion: @escaping AnimationCompletion) throws {
try presentationContext = getPresentationContext()
install()
- self.config.eventListeners.forEach { $0(.willShow) }
+ self.config.eventListeners.forEach { $0(.willShow(self.view)) }
showAnimation() { completed in
completion(completed)
if completed {
@@ -128,7 +128,7 @@ class Presenter: NSObject {
} else {
self.showAccessibilityAnnouncement()
}
- self.config.eventListeners.forEach { $0(.didShow) }
+ self.config.eventListeners.forEach { $0(.didShow(self.view)) }
}
}
}
@@ -181,7 +181,7 @@ class Presenter: NSObject {
func hide(animated: Bool, completion: @escaping AnimationCompletion) {
isHiding = true
- self.config.eventListeners.forEach { $0(.willHide) }
+ self.config.eventListeners.forEach { $0(.willHide(self.view)) }
let context = animationContext()
let action = {
if let viewController = self.presentationContext.viewControllerValue() as? WindowViewController {
@@ -189,7 +189,7 @@ class Presenter: NSObject {
}
self.maskingView.removeFromSuperview()
completion(true)
- self.config.eventListeners.forEach { $0(.didHide) }
+ self.config.eventListeners.forEach { $0(.didHide(self.view)) }
}
guard animated else {
action()
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index 7c0042f..5e9f0c3 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -219,10 +219,23 @@ open class SwiftMessages {
Specifies events in the message lifecycle.
*/
public enum Event {
- case willShow
- case didShow
- case willHide
- case didHide
+ case willShow(UIView)
+ case didShow(UIView)
+ case willHide(UIView)
+ case didHide(UIView)
+
+ public var view: UIView {
+ switch self {
+ case .willShow(let view): return view
+ case .didShow(let view): return view
+ case .willHide(let view): return view
+ case .didHide(let view): return view
+ }
+ }
+
+ public var id: String? {
+ return (view as? Identifiable)?.id
+ }
}
/**
From 4e49214f64f949cc00af225e1f6f4457f6fd62d5 Mon Sep 17 00:00:00 2001
From: mbastos
Date: Sat, 14 May 2022 13:59:22 -0300
Subject: [PATCH 10/38] Add dynamically linked option in products (#495)
---
Package.swift | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Package.swift b/Package.swift
index 5324d1b..a0f30e8 100644
--- a/Package.swift
+++ b/Package.swift
@@ -7,7 +7,8 @@ let package = Package(
.iOS("9.0")
],
products: [
- .library(name: "SwiftMessages", targets: ["SwiftMessages"])
+ .library(name: "SwiftMessages", targets: ["SwiftMessages"]),
+ .library(name: "SwiftMessages-Dynamic", type: .dynamic, targets: ["SwiftMessages"])
],
targets: [
.target(
From 3af7c4d5abf1a023c375b4f7d78f32cf12d02e5b Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Mon, 18 Sep 2023 11:56:20 -0500
Subject: [PATCH 11/38] Prevent orphaned views from blocking (#517)
---
SwiftMessages/Presenter.swift | 10 +++++++++-
SwiftMessages/SwiftMessages.swift | 8 ++++++--
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/SwiftMessages/Presenter.swift b/SwiftMessages/Presenter.swift
index be093be..5a3648b 100644
--- a/SwiftMessages/Presenter.swift
+++ b/SwiftMessages/Presenter.swift
@@ -68,6 +68,13 @@ class Presenter: NSObject {
return duration
}
+ /// Detects the scenario where the view was shown, but the containing view heirarchy was removed before the view
+ /// was hidden. This unusual scenario could result in the message queue being blocked because the presented
+ /// view was not properly hidden by SwiftMessages. `isOrphaned` allows the queuing logic to unblock the queue.
+ var isOrphaned: Bool {
+ return installed && view.window == nil
+ }
+
// MARK: - Constants
enum PresentationContext {
@@ -97,7 +104,7 @@ class Presenter: NSObject {
private weak var delegate: PresenterDelegate?
private var presentationContext = PresentationContext.viewController(Weak(value: nil))
-
+ private var installed = false
private var interactivelyHidden = false;
// MARK: - Showing and hiding
@@ -412,6 +419,7 @@ class Presenter: NSObject {
maskingView.accessibleElements = elements
}
+ installed = true
guard let containerView = presentationContext.viewValue() else { return }
(presentationContext.viewControllerValue() as? WindowViewController)?.install()
installMaskingView(containerView: containerView)
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index 5e9f0c3..395bc0a 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -586,7 +586,10 @@ open class SwiftMessages {
fileprivate func enqueue(presenter: Presenter) {
if presenter.config.ignoreDuplicates {
counts[presenter.id] = (counts[presenter.id] ?? 0) + 1
- if _current?.id == presenter.id && _current?.isHiding == false { return }
+ if let _current,
+ _current.id == presenter.id,
+ !_current.isHiding,
+ !_current.isOrphaned { return }
if queue.filter({ $0.id == presenter.id }).count > 0 { return }
}
func doEnqueue() {
@@ -606,7 +609,8 @@ open class SwiftMessages {
}
fileprivate func dequeueNext() {
- guard self._current == nil, queue.count > 0 else { return }
+ guard queue.count > 0 else { return }
+ if let _current, !_current.isOrphaned { return }
let current = queue.removeFirst()
self._current = current
// Set `autohideToken` before the animation starts in case
From 977436eeef05a0a21bee8e7f651cd12f5b7ef191 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Mon, 18 Sep 2023 12:12:49 -0500
Subject: [PATCH 12/38] Remove unowned reference
---
SwiftMessages/SwiftMessagesSegue.swift | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/SwiftMessages/SwiftMessagesSegue.swift b/SwiftMessages/SwiftMessagesSegue.swift
index d4cba41..80c3939 100644
--- a/SwiftMessages/SwiftMessagesSegue.swift
+++ b/SwiftMessages/SwiftMessagesSegue.swift
@@ -208,6 +208,7 @@ open class SwiftMessagesSegue: UIStoryboardSegue {
override open func perform() {
(source as? WindowViewController)?.install()
selfRetainer = self
+ startReleaseMonitor()
if overrideModalPresentationStyle {
destination.modalPresentationStyle = .custom
}
@@ -222,6 +223,19 @@ open class SwiftMessagesSegue: UIStoryboardSegue {
}
fileprivate let safeAreaWorkaroundViewController = UIViewController()
+
+ /// The self-retainer will not allow the segue, presenting and presented view controllers to be released if the presenting view controller
+ /// is removed without first dismissing. This monitor handles that scenario by setting `self.selfRetainer = nil` if
+ /// the presenting view controller is no longer in the heirarchy.
+ private func startReleaseMonitor() {
+ DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
+ guard let self = self else { return }
+ switch self.source.view.window {
+ case .none: self.selfRetainer = nil
+ case .some: self.startReleaseMonitor()
+ }
+ }
+ }
}
extension SwiftMessagesSegue {
@@ -288,12 +302,13 @@ extension SwiftMessagesSegue {
extension SwiftMessagesSegue: UIViewControllerTransitioningDelegate {
public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let shower = TransitioningPresenter(segue: self)
- messenger.defaultConfig.eventListeners.append { [unowned self] in
+ let hider = self.hider
+ messenger.defaultConfig.eventListeners.append { [weak self] in
switch $0 {
case .didShow:
shower.completeTransition?(true)
case .didHide:
- if let completeTransition = self.hider.completeTransition {
+ if let completeTransition = hider.completeTransition {
completeTransition(true)
} else {
// Case where message is internally hidden by SwiftMessages, such as with a
@@ -301,7 +316,7 @@ extension SwiftMessagesSegue: UIViewControllerTransitioningDelegate {
source.dismiss(animated: false, completion: nil)
}
(source as? WindowViewController)?.uninstall()
- self.selfRetainer = nil
+ self?.selfRetainer = nil
default: break
}
}
From 813938a829bc0599712c9001eb2298cc0ffe6fb6 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Mon, 18 Sep 2023 12:13:02 -0500
Subject: [PATCH 13/38] Update changelog
---
CHANGELOG.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8c25038..0a4ec93 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,14 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 9.0.7
+
+### Fixes
+
+* #527 Crash while clicking two times to hide the presenting controller
+* #517 Prevent orphaned views from blocking the queue
+* Prevent orphaned `SwiftMessagesSeque`s from retaining the presenting view controller
+
## 9.0.6
### Features
From 6c16e58ce72f8e7549930e3d2c62e25e224e799b Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Fri, 6 Oct 2023 09:38:19 -0500
Subject: [PATCH 14/38] Add basic support for SwiftUI (#528)
---
README.md | 103 ++++-
SwiftMessages.podspec | 6 +-
SwiftMessages.xcodeproj/project.pbxproj | 72 ++-
.../xcschemes/SwiftMessages.xcscheme | 2 +-
SwiftMessages/BaseView.swift | 4 +-
SwiftMessages/Identifiable.swift | 1 +
SwiftMessages/MessageHostingView.swift | 42 ++
SwiftMessages/MessageViewConvertible.swift | 16 +
SwiftMessages/SwiftMessageModifier.swift | 62 +++
SwiftMessages/SwiftMessagesSegue.swift | 8 -
.../SwiftUIDemo.xcodeproj/project.pbxproj | 436 ++++++++++++++++++
.../contents.xcworkspacedata | 7 +
.../xcshareddata/IDEWorkspaceChecks.plist | 8 +
.../AccentColor.colorset/Contents.json | 11 +
.../AppIcon.appiconset/Contents.json | 13 +
.../SwiftUIDemo/Assets.xcassets/Contents.json | 6 +
.../Contents.json | 20 +
SwiftUIDemo/SwiftUIDemo/DemoMessage.swift | 22 +
SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift | 35 ++
SwiftUIDemo/SwiftUIDemo/DemoView.swift | 48 ++
SwiftUIDemo/SwiftUIDemo/Info.plist | 5 +
.../Preview Assets.xcassets/Contents.json | 6 +
SwiftUIDemo/SwiftUIDemo/SwiftUIDemoApp.swift | 17 +
23 files changed, 910 insertions(+), 40 deletions(-)
create mode 100644 SwiftMessages/MessageHostingView.swift
create mode 100644 SwiftMessages/MessageViewConvertible.swift
create mode 100644 SwiftMessages/SwiftMessageModifier.swift
create mode 100644 SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
create mode 100644 SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
create mode 100644 SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
create mode 100644 SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AccentColor.colorset/Contents.json
create mode 100644 SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json
create mode 100644 SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json
create mode 100644 SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Demo message background.colorset/Contents.json
create mode 100644 SwiftUIDemo/SwiftUIDemo/DemoMessage.swift
create mode 100644 SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
create mode 100644 SwiftUIDemo/SwiftUIDemo/DemoView.swift
create mode 100644 SwiftUIDemo/SwiftUIDemo/Info.plist
create mode 100644 SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json
create mode 100644 SwiftUIDemo/SwiftUIDemo/SwiftUIDemoApp.swift
diff --git a/README.md b/README.md
index 97e8374..0cf8e79 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,8 @@ SwiftMessages is a very flexible view and view controller presentation library f
Message views and view controllers can be displayed at the top, bottom, or center of the screen, or behind navigation bars and tab bars. There are interactive dismiss gestures including a fun, physics-based one. Multiple background dimming modes. And a lot more!
+🔥 Now supports displaying SwiftUI message views 🔥
+
In addition to the numerous configuration options, SwiftMessages provides several good-looking layouts and themes. But SwiftMessages is also designer-friendly, which means you can fully and easily customize the view:
* Copy one of the included nib files into your project and change it.
@@ -32,19 +34,6 @@ Try exploring [the demo app via appetize.io](http://goo.gl/KXw4nD) to get a feel
-## View Controllers
-
-SwiftMessages can present view controllers using the `SwiftMessagesSegue` custom modal segue!
-
-
-
-
-
-[`SwiftMessagesSegue`](./SwiftMessages/SwiftMessagesSegue.swift) is a subclass of `UIStoryboardSegue` that integrates directly into Interface Builder as a custom modal segue, enabling view controllers to take advantage of SwiftMessages layouts, animations and more. `SwiftMessagesSegue` works with any UIKIt project — storyboards are not required. Refer to the View Controllers readme below for more information.
-
-#### [View Controllers Readme](./ViewControllers.md)
-
-And check out our blog post [Elegant Custom UIViewController Transitioning](http://www.swiftkickmobile.com/elegant-custom-uiviewcontroller-transitioning-uiviewcontrollertransitioningdelegate-uiviewcontrolleranimatedtransitioning/) to learn a great technique you can use to build your own custom segues that utilize `UIViewControllerTransitioningDelegate` and `UIViewControllerAnimatedTransitioning`.
## Installation
@@ -178,6 +167,94 @@ config.duration = .forever
SwiftMessages.show(config: config, view: view)
````
+### View Controllers
+
+SwiftMessages can present view controllers using the `SwiftMessagesSegue` custom modal segue!
+
+
+
+
+
+[`SwiftMessagesSegue`](./SwiftMessages/SwiftMessagesSegue.swift) is a subclass of `UIStoryboardSegue` that integrates directly into Interface Builder as a custom modal segue, enabling view controllers to take advantage of SwiftMessages layouts, animations and more. `SwiftMessagesSegue` works with any UIKIt project — storyboards are not required. Refer to the View Controllers readme below for more information.
+
+#### [View Controllers Readme](./ViewControllers.md)
+
+And check out our blog post [Elegant Custom UIViewController Transitioning](http://www.swiftkickmobile.com/elegant-custom-uiviewcontroller-transitioning-uiviewcontrollertransitioningdelegate-uiviewcontrolleranimatedtransitioning/) to learn a great technique you can use to build your own custom segues that utilize `UIViewControllerTransitioningDelegate` and `UIViewControllerAnimatedTransitioning`.
+
+### SwiftUI
+
+Any of the built-in SwiftMessages views can be displayed by calling the SwiftMessages APIs from within observable object, a button action closure, etc. However, SwiftMessages can also display your custom SwiftUI views.
+
+First, define a type that conforms to `MessageViewConvertible`. This will typically be a struct containing the message data:
+
+
+````swift
+struct DemoMessage: Identifiable {
+ let title: String
+ let body: String
+
+ var id: String { title + body }
+}
+
+extension DemoMessage: MessageViewConvertible {
+ func asMessageView() -> DemoMessageView {
+ DemoMessageView(message: self)
+ }
+}
+
+struct DemoMessageView: View {
+
+ let message: DemoMessage
+
+ var body: some View {
+ VStack(alignment: .leading) {
+ Text(message.title).font(.system(size: 20, weight: .bold))
+ Text(message.body)
+ }
+ .multilineTextAlignment(.leading)
+ .padding(30)
+ .frame(maxWidth: .infinity)
+ .background(.gray)
+ .cornerRadius(15)
+ .padding(15)
+ }
+}
+````
+
+The SwiftUI message view can be displayed just like any other UIKit message by using `MessageHostingView`:
+
+````swift
+struct DemoView: View {
+ var body: some View {
+ Button("Show message") {
+ let message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
+ let messageView = MessageHostingView(message: message)
+ SwiftMessages.show(view: messageView)
+ }
+ }
+}
+````
+
+But you may also use a state-based approach using the `swiftMessage()` view modifier:
+
+````swift
+struct DemoView: View {
+
+ @State var message: DemoMessage?
+
+ var body: some View {
+ Button("Show message") {
+ message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
+ }
+ .swiftMessage(message: $message)
+ }
+}
+````
+
+This technique may be more SwiftUI-like, but it doesn't offer the full capability of SwiftMessages, such as explicitly hiding messages by their ID. It is totally reasonable to use a combination of both approaches.
+
+Try it out in the SwiftUI demo app!
+
### Accessibility
SwiftMessages provides excellent VoiceOver support out-of-the-box.
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index 4c7b945..00b6a81 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,14 +1,14 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '9.0.6'
+ spec.version = '9.0.7'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkick.it' }
spec.summary = 'A very flexible message bar for iOS written in Swift.'
spec.source = {:git => 'https://github.com/SwiftKickMobile/SwiftMessages.git', :tag => spec.version}
- spec.platform = :ios, '9.0'
+ spec.platform = :ios, '12.0'
spec.swift_version = '5.0'
- spec.ios.deployment_target = '9.0'
+ spec.ios.deployment_target = '12.0'
spec.framework = 'UIKit'
spec.requires_arc = true
spec.default_subspec = 'App'
diff --git a/SwiftMessages.xcodeproj/project.pbxproj b/SwiftMessages.xcodeproj/project.pbxproj
index b01d9c2..45809f2 100644
--- a/SwiftMessages.xcodeproj/project.pbxproj
+++ b/SwiftMessages.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 46;
+ objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@@ -52,6 +52,9 @@
228DF5681FAD0806004F8A39 /* infoIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = 228DF5471FAD0805004F8A39 /* infoIconSubtle.png */; };
228DF5691FAD0806004F8A39 /* successIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 228DF5481FAD0805004F8A39 /* successIconLight.png */; };
228DF56A1FAD0806004F8A39 /* infoIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 228DF5491FAD0805004F8A39 /* infoIconSubtle@3x.png */; };
+ 228F7DDE2ACF703A006C9644 /* MessageHostingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DDB2ACF7039006C9644 /* MessageHostingView.swift */; };
+ 228F7DDF2ACF703A006C9644 /* SwiftMessageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DDC2ACF703A006C9644 /* SwiftMessageModifier.swift */; };
+ 228F7DE02ACF703A006C9644 /* MessageViewConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DDD2ACF703A006C9644 /* MessageViewConvertible.swift */; };
2298C2051EE47DC900E2DDC1 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2041EE47DC900E2DDC1 /* Weak.swift */; };
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2061EE480D000E2DDC1 /* Animator.swift */; };
2298C2091EE486E300E2DDC1 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */; };
@@ -140,6 +143,9 @@
228DF5471FAD0805004F8A39 /* infoIconSubtle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = infoIconSubtle.png; path = Resources/infoIconSubtle.png; sourceTree = ""; };
228DF5481FAD0805004F8A39 /* successIconLight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = successIconLight.png; path = Resources/successIconLight.png; sourceTree = ""; };
228DF5491FAD0805004F8A39 /* infoIconSubtle@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "infoIconSubtle@3x.png"; path = "Resources/infoIconSubtle@3x.png"; sourceTree = ""; };
+ 228F7DDB2ACF7039006C9644 /* MessageHostingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHostingView.swift; sourceTree = ""; };
+ 228F7DDC2ACF703A006C9644 /* SwiftMessageModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftMessageModifier.swift; sourceTree = ""; };
+ 228F7DDD2ACF703A006C9644 /* MessageViewConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageViewConvertible.swift; sourceTree = ""; };
2298C2041EE47DC900E2DDC1 /* Weak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = ""; };
2298C2061EE480D000E2DDC1 /* Animator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animator.swift; sourceTree = ""; };
2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopBottomAnimation.swift; sourceTree = ""; };
@@ -235,6 +241,15 @@
name = Frameworks;
sourceTree = "";
};
+ 228F7DDA2ACF7029006C9644 /* SwiftUI */ = {
+ isa = PBXGroup;
+ children = (
+ 228F7DDC2ACF703A006C9644 /* SwiftMessageModifier.swift */,
+ 228F7DDD2ACF703A006C9644 /* MessageViewConvertible.swift */,
+ );
+ name = SwiftUI;
+ sourceTree = "";
+ };
22D4779B20BF1C54005D0D71 /* View Controllers */ = {
isa = PBXGroup;
children = (
@@ -339,6 +354,7 @@
86AAF8171D54F0650031EE32 /* PassthroughView.swift */,
22E01F631E74EC8B00ACE19A /* MaskingView.swift */,
86AAF8191D54F0850031EE32 /* PassthroughWindow.swift */,
+ 228F7DDB2ACF7039006C9644 /* MessageHostingView.swift */,
220D38672597A94C00BB2B88 /* Extensions */,
);
name = Internal;
@@ -352,6 +368,7 @@
862C0CD81D5A396900D06168 /* Resources */,
2244656C1EF1D62700C50413 /* Animations */,
22D4779B20BF1C54005D0D71 /* View Controllers */,
+ 228F7DDA2ACF7029006C9644 /* SwiftUI */,
864495571D4F7C490056EB2A /* Base */,
220D38682597A9FD00BB2B88 /* Extensions */,
867E218E1D4D3DFD00594A41 /* Internal */,
@@ -434,8 +451,9 @@
867E21471D4D01D500594A41 /* Project object */ = {
isa = PBXProject;
attributes = {
+ BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 0730;
- LastUpgradeCheck = 1200;
+ LastUpgradeCheck = 1500;
ORGANIZATIONNAME = "SwiftKick Mobile";
TargetAttributes = {
86B48AEB1D5A41C900063E2B = {
@@ -539,13 +557,16 @@
86BBA9011D5E040600FE8F16 /* PassthroughWindow.swift in Sources */,
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */,
86BBA9031D5E040600FE8F16 /* UIViewController+Extensions.swift in Sources */,
+ 228F7DDF2ACF703A006C9644 /* SwiftMessageModifier.swift in Sources */,
224FB69921153B440081D4DE /* CALayer+Extensions.swift in Sources */,
22E01F641E74EC8B00ACE19A /* MaskingView.swift in Sources */,
2298C2051EE47DC900E2DDC1 /* Weak.swift in Sources */,
+ 228F7DE02ACF703A006C9644 /* MessageViewConvertible.swift in Sources */,
86BBA9001D5E040600FE8F16 /* PassthroughView.swift in Sources */,
22DFC9181F00674E001B1CA1 /* PhysicsPanHandler.swift in Sources */,
227BA6D920BF224A00E5A843 /* SwiftMessagesSegue.swift in Sources */,
220655121FAF82B600F4E00F /* MarginAdjustable+Extensions.swift in Sources */,
+ 228F7DDE2ACF703A006C9644 /* MessageHostingView.swift in Sources */,
22E307FF1E74C5B100E35893 /* AccessibleMessage.swift in Sources */,
220D386E2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift in Sources */,
2270044B1FAFA6DD0045DDC3 /* PhysicsAnimation.swift in Sources */,
@@ -619,6 +640,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -633,7 +655,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.1;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -677,6 +699,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -685,10 +708,11 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.1;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 3.0;
VALIDATE_PRODUCT = YES;
};
@@ -698,17 +722,24 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+ CODE_SIGN_IDENTITY = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_MODULE_VERIFIER = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
INFOPLIST_FILE = SwiftMessages/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
+ MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11";
PRODUCT_BUNDLE_IDENTIFIER = it.swiftkick.SwiftMessages;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -726,17 +757,24 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
+ CODE_SIGN_IDENTITY = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_MODULE_VERIFIER = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
INFOPLIST_FILE = SwiftMessages/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
+ MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11";
PRODUCT_BUNDLE_IDENTIFIER = it.swiftkick.SwiftMessages;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -753,7 +791,11 @@
isa = XCBuildConfiguration;
buildSettings = {
INFOPLIST_FILE = SwiftMessagesTests/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = it.swiftkick.SwiftMessagesTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
@@ -765,7 +807,11 @@
isa = XCBuildConfiguration;
buildSettings = {
INFOPLIST_FILE = SwiftMessagesTests/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
PRODUCT_BUNDLE_IDENTIFIER = it.swiftkick.SwiftMessagesTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
diff --git a/SwiftMessages.xcodeproj/xcshareddata/xcschemes/SwiftMessages.xcscheme b/SwiftMessages.xcodeproj/xcshareddata/xcschemes/SwiftMessages.xcscheme
index ad3b253..5c84455 100644
--- a/SwiftMessages.xcodeproj/xcshareddata/xcschemes/SwiftMessages.xcscheme
+++ b/SwiftMessages.xcodeproj/xcshareddata/xcschemes/SwiftMessages.xcscheme
@@ -1,6 +1,6 @@
: BaseView, Identifiable where Content: View {
+
+ // MARK: - API
+
+ public let id: String
+
+ public init(message: Message) where Message: MessageViewConvertible, Message.Content == Content {
+ let messageView: Content = message.asMessageView()
+ hostVC = UIHostingController(rootView: messageView)
+ id = message.id
+ super.init(frame: .zero)
+ hostVC.loadViewIfNeeded()
+ installContentView(hostVC.view)
+ backgroundColor = .clear
+ hostVC.view.backgroundColor = .clear
+ }
+
+ // MARK: - Constants
+
+ // MARK: - Variables
+
+ private let hostVC: UIHostingController
+
+ // MARK: - Lifecycle
+
+ @available(*, unavailable)
+ required init?(coder _: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/SwiftMessages/MessageViewConvertible.swift b/SwiftMessages/MessageViewConvertible.swift
new file mode 100644
index 0000000..6dc168b
--- /dev/null
+++ b/SwiftMessages/MessageViewConvertible.swift
@@ -0,0 +1,16 @@
+//
+// MessageViewConvertible.swift
+// SwiftUIDemo
+//
+// Created by Timothy Moose on 10/5/23.
+//
+
+import SwiftUI
+
+@available(iOS 14.0, *)
+/// A protocol used to display a SwiftUI message view using the `swiftMessage()` modifier.
+public protocol MessageViewConvertible: Equatable, Identifiable {
+ associatedtype Content: View
+ func asMessageView() -> Content
+}
+
diff --git a/SwiftMessages/SwiftMessageModifier.swift b/SwiftMessages/SwiftMessageModifier.swift
new file mode 100644
index 0000000..479b6d9
--- /dev/null
+++ b/SwiftMessages/SwiftMessageModifier.swift
@@ -0,0 +1,62 @@
+//
+// SwiftMessageModifier.swift
+// SwiftUIDemo
+//
+// Created by Timothy Moose on 10/5/23.
+//
+
+import SwiftUI
+
+@available(iOS 14.0, *)
+public extension View {
+ /// A state-based modifier for displaying a message.
+ func swiftMessage(
+ message: Binding,
+ config: SwiftMessages.Config? = nil,
+ swiftMessages: SwiftMessages? = nil
+ ) -> some View where Message: MessageViewConvertible {
+ modifier(SwiftMessageModifier(message: message, config: config, swiftMessages: swiftMessages))
+ }
+}
+
+@available(iOS 14.0, *)
+private struct SwiftMessageModifier: ViewModifier where Message: MessageViewConvertible {
+ // MARK: - API
+
+ fileprivate init(
+ message: Binding,
+ config: SwiftMessages.Config? = nil,
+ swiftMessages: SwiftMessages? = nil
+ ) {
+ _message = message
+ self.config = config
+ self.swiftMessages = swiftMessages
+ }
+
+ // MARK: - Constants
+
+ // MARK: - Variables
+
+ @Binding private var message: Message?
+ private let config: SwiftMessages.Config?
+ private let swiftMessages: SwiftMessages?
+
+ // MARK: - Body
+
+ func body(content: Content) -> some View {
+ content
+ .onChange(of: message) { _ in
+ if let message {
+ let show: (SwiftMessages.Config, UIView) -> Void = swiftMessages?.show(config:view:) ?? SwiftMessages.show(config:view:)
+ let view = MessageHostingView(message: message)
+ var config = config ?? swiftMessages?.defaultConfig ?? SwiftMessages.defaultConfig
+ config.eventListeners.append { event in
+ if case .didHide = event, event.id == self.message?.id {
+ self.message = nil
+ }
+ }
+ show(config, view)
+ }
+ }
+ }
+}
diff --git a/SwiftMessages/SwiftMessagesSegue.swift b/SwiftMessages/SwiftMessagesSegue.swift
index 80c3939..cd17eec 100644
--- a/SwiftMessages/SwiftMessagesSegue.swift
+++ b/SwiftMessages/SwiftMessagesSegue.swift
@@ -348,14 +348,6 @@ extension SwiftMessagesSegue {
transitionContext.completeTransition(false)
return
}
- if #available(iOS 12, *) {}
- else if #available(iOS 11.0, *) {
- // This works around a bug in iOS 11 where the safe area of `messageView` (
- // and all ancestor views) is not set except on iPhone X. By assigning `messageView`
- // to a view controller, its safe area is set consistently. This bug has been resolved as
- // of Xcode 10 beta 2.
- segue.safeAreaWorkaroundViewController.view = segue.presenter.maskingView
- }
completeTransition = transitionContext.completeTransition
let transitionContainer = transitionContext.containerView
toView.translatesAutoresizingMaskIntoConstraints = false
diff --git a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..8b289e2
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
@@ -0,0 +1,436 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 56;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 228F7DAD2ACF17E8006C9644 /* SwiftUIDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DAC2ACF17E8006C9644 /* SwiftUIDemoApp.swift */; };
+ 228F7DAF2ACF17E8006C9644 /* DemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DAE2ACF17E8006C9644 /* DemoView.swift */; };
+ 228F7DB12ACF17E9006C9644 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 228F7DB02ACF17E9006C9644 /* Assets.xcassets */; };
+ 228F7DB42ACF17E9006C9644 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 228F7DB32ACF17E9006C9644 /* Preview Assets.xcassets */; };
+ 228F7DC82ACF1E63006C9644 /* SwiftMessages.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 228F7DC32ACF1E1E006C9644 /* SwiftMessages.framework */; };
+ 228F7DC92ACF1E63006C9644 /* SwiftMessages.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 228F7DC32ACF1E1E006C9644 /* SwiftMessages.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 228F7DD52ACF59E4006C9644 /* DemoMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DD42ACF59E4006C9644 /* DemoMessage.swift */; };
+ 228F7DD72ACF5C2E006C9644 /* DemoMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DD62ACF5C2E006C9644 /* DemoMessageView.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 228F7DC22ACF1E1E006C9644 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 228F7DBD2ACF1E1E006C9644 /* SwiftMessages.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 86B48AEC1D5A41C900063E2B;
+ remoteInfo = SwiftMessages;
+ };
+ 228F7DC42ACF1E1E006C9644 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 228F7DBD2ACF1E1E006C9644 /* SwiftMessages.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 86B48AF51D5A41C900063E2B;
+ remoteInfo = SwiftMessagesTests;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 228F7DCA2ACF1E63006C9644 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 228F7DC92ACF1E63006C9644 /* SwiftMessages.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 228F7DA92ACF17E8006C9644 /* SwiftUIDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUIDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 228F7DAC2ACF17E8006C9644 /* SwiftUIDemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIDemoApp.swift; sourceTree = ""; };
+ 228F7DAE2ACF17E8006C9644 /* DemoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoView.swift; sourceTree = ""; };
+ 228F7DB02ACF17E9006C9644 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 228F7DB32ACF17E9006C9644 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
+ 228F7DBB2ACF1DB5006C9644 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
+ 228F7DBD2ACF1E1E006C9644 /* SwiftMessages.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SwiftMessages.xcodeproj; path = ../SwiftMessages.xcodeproj; sourceTree = ""; };
+ 228F7DD42ACF59E4006C9644 /* DemoMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoMessage.swift; sourceTree = ""; };
+ 228F7DD62ACF5C2E006C9644 /* DemoMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoMessageView.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 228F7DA62ACF17E8006C9644 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 228F7DC82ACF1E63006C9644 /* SwiftMessages.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 228F7DA02ACF17E8006C9644 = {
+ isa = PBXGroup;
+ children = (
+ 228F7DAB2ACF17E8006C9644 /* SwiftUIDemo */,
+ 228F7DAA2ACF17E8006C9644 /* Products */,
+ 228F7DC72ACF1E63006C9644 /* Frameworks */,
+ 228F7DBD2ACF1E1E006C9644 /* SwiftMessages.xcodeproj */,
+ );
+ sourceTree = "";
+ };
+ 228F7DAA2ACF17E8006C9644 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 228F7DA92ACF17E8006C9644 /* SwiftUIDemo.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 228F7DAB2ACF17E8006C9644 /* SwiftUIDemo */ = {
+ isa = PBXGroup;
+ children = (
+ 228F7DBB2ACF1DB5006C9644 /* Info.plist */,
+ 228F7DAC2ACF17E8006C9644 /* SwiftUIDemoApp.swift */,
+ 228F7DAE2ACF17E8006C9644 /* DemoView.swift */,
+ 228F7DD42ACF59E4006C9644 /* DemoMessage.swift */,
+ 228F7DD62ACF5C2E006C9644 /* DemoMessageView.swift */,
+ 228F7DB02ACF17E9006C9644 /* Assets.xcassets */,
+ 228F7DB22ACF17E9006C9644 /* Preview Content */,
+ );
+ path = SwiftUIDemo;
+ sourceTree = "";
+ };
+ 228F7DB22ACF17E9006C9644 /* Preview Content */ = {
+ isa = PBXGroup;
+ children = (
+ 228F7DB32ACF17E9006C9644 /* Preview Assets.xcassets */,
+ );
+ path = "Preview Content";
+ sourceTree = "";
+ };
+ 228F7DBE2ACF1E1E006C9644 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 228F7DC32ACF1E1E006C9644 /* SwiftMessages.framework */,
+ 228F7DC52ACF1E1E006C9644 /* SwiftMessagesTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 228F7DC72ACF1E63006C9644 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 228F7DA82ACF17E8006C9644 /* SwiftUIDemo */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 228F7DB72ACF17E9006C9644 /* Build configuration list for PBXNativeTarget "SwiftUIDemo" */;
+ buildPhases = (
+ 228F7DA52ACF17E8006C9644 /* Sources */,
+ 228F7DA62ACF17E8006C9644 /* Frameworks */,
+ 228F7DA72ACF17E8006C9644 /* Resources */,
+ 228F7DCA2ACF1E63006C9644 /* Embed Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SwiftUIDemo;
+ productName = SwiftUIDemo;
+ productReference = 228F7DA92ACF17E8006C9644 /* SwiftUIDemo.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 228F7DA12ACF17E8006C9644 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1500;
+ LastUpgradeCheck = 1500;
+ TargetAttributes = {
+ 228F7DA82ACF17E8006C9644 = {
+ CreatedOnToolsVersion = 15.0;
+ };
+ };
+ };
+ buildConfigurationList = 228F7DA42ACF17E8006C9644 /* Build configuration list for PBXProject "SwiftUIDemo" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 228F7DA02ACF17E8006C9644;
+ productRefGroup = 228F7DAA2ACF17E8006C9644 /* Products */;
+ projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = 228F7DBE2ACF1E1E006C9644 /* Products */;
+ ProjectRef = 228F7DBD2ACF1E1E006C9644 /* SwiftMessages.xcodeproj */;
+ },
+ );
+ projectRoot = "";
+ targets = (
+ 228F7DA82ACF17E8006C9644 /* SwiftUIDemo */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+ 228F7DC32ACF1E1E006C9644 /* SwiftMessages.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = SwiftMessages.framework;
+ remoteRef = 228F7DC22ACF1E1E006C9644 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 228F7DC52ACF1E1E006C9644 /* SwiftMessagesTests.xctest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = SwiftMessagesTests.xctest;
+ remoteRef = 228F7DC42ACF1E1E006C9644 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 228F7DA72ACF17E8006C9644 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 228F7DB42ACF17E9006C9644 /* Preview Assets.xcassets in Resources */,
+ 228F7DB12ACF17E9006C9644 /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 228F7DA52ACF17E8006C9644 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 228F7DD52ACF59E4006C9644 /* DemoMessage.swift in Sources */,
+ 228F7DD72ACF5C2E006C9644 /* DemoMessageView.swift in Sources */,
+ 228F7DAF2ACF17E8006C9644 /* DemoView.swift in Sources */,
+ 228F7DAD2ACF17E8006C9644 /* SwiftUIDemoApp.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 228F7DB52ACF17E9006C9644 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.0;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ 228F7DB62ACF17E9006C9644 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.0;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 228F7DB82ACF17E9006C9644 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"SwiftUIDemo/Preview Content\"";
+ ENABLE_PREVIEWS = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = SwiftUIDemo/Info.plist;
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchScreen_Generation = YES;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.swiftkickmobile.SwiftUIDemo;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 228F7DB92ACF17E9006C9644 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"SwiftUIDemo/Preview Content\"";
+ ENABLE_PREVIEWS = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = SwiftUIDemo/Info.plist;
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchScreen_Generation = YES;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.swiftkickmobile.SwiftUIDemo;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 228F7DA42ACF17E8006C9644 /* Build configuration list for PBXProject "SwiftUIDemo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 228F7DB52ACF17E9006C9644 /* Debug */,
+ 228F7DB62ACF17E9006C9644 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 228F7DB72ACF17E9006C9644 /* Build configuration list for PBXNativeTarget "SwiftUIDemo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 228F7DB82ACF17E9006C9644 /* Debug */,
+ 228F7DB92ACF17E9006C9644 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 228F7DA12ACF17E8006C9644 /* Project object */;
+}
diff --git a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AccentColor.colorset/Contents.json b/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..13613e3
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,13 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json b/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Demo message background.colorset/Contents.json b/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Demo message background.colorset/Contents.json
new file mode 100644
index 0000000..15b79d4
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/Assets.xcassets/Demo message background.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xEB",
+ "green" : "0xE1",
+ "red" : "0xAC"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoMessage.swift b/SwiftUIDemo/SwiftUIDemo/DemoMessage.swift
new file mode 100644
index 0000000..ccc86b6
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/DemoMessage.swift
@@ -0,0 +1,22 @@
+//
+// DemoMessage.swift
+// SwiftUIDemo
+//
+// Created by Timothy Moose on 10/5/23.
+//
+
+import SwiftUI
+import SwiftMessages
+
+struct DemoMessage: Identifiable {
+ let title: String
+ let body: String
+
+ var id: String { title + body }
+}
+
+extension DemoMessage: MessageViewConvertible {
+ func asMessageView() -> DemoMessageView {
+ DemoMessageView(message: self)
+ }
+}
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift b/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
new file mode 100644
index 0000000..cce5058
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
@@ -0,0 +1,35 @@
+//
+// DemoMessageView.swift
+// SwiftUIDemo
+//
+// Created by Timothy Moose on 10/5/23.
+//
+
+import SwiftUI
+
+struct DemoMessageView: View {
+
+ // MARK: - API
+
+ let message: DemoMessage
+
+ // MARK: - Variables
+
+ // MARK: - Constants
+
+ // MARK: - Body
+
+ var body: some View {
+ VStack(alignment: .leading) {
+ Text(message.title).font(.system(size: 20, weight: .bold))
+ Text(message.body)
+ }
+ .multilineTextAlignment(.leading)
+ .padding(30)
+ .frame(maxWidth: .infinity)
+ .background(.demoMessageBackground)
+ .cornerRadius(15)
+ .padding(15)
+ }
+}
+
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoView.swift b/SwiftUIDemo/SwiftUIDemo/DemoView.swift
new file mode 100644
index 0000000..e0bcd6c
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/DemoView.swift
@@ -0,0 +1,48 @@
+//
+// DemoView.swift
+// SwiftUIDemo
+//
+// Created by Timothy Moose on 10/5/23.
+//
+
+import SwiftUI
+import SwiftMessages
+
+struct DemoView: View {
+
+ @State var message: DemoMessage?
+
+ var body: some View {
+ Button("Show message") {
+ message = DemoMessage(title: "Demo", body: "This is a sample SwiftUI message! This content should be long enough to wrap.")
+ }
+ .buttonBorderShape(.roundedRectangle(radius: 15))
+ .swiftMessage(message: $message)
+ }
+}
+
+#Preview {
+ DemoView()
+}
+
+struct DemoViewx: View {
+ var body: some View {
+ Button("Show message") {
+ let message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
+ let messageView = MessageHostingView(message: message)
+ SwiftMessages.show(view: messageView)
+ }
+ }
+}
+
+struct DemoViewy: View {
+
+ @State var message: DemoMessage?
+
+ var body: some View {
+ Button("Show message") {
+ message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
+ }
+ .swiftMessage(message: $message)
+ }
+}
diff --git a/SwiftUIDemo/SwiftUIDemo/Info.plist b/SwiftUIDemo/SwiftUIDemo/Info.plist
new file mode 100644
index 0000000..0c67376
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/Info.plist
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json b/SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SwiftUIDemo/SwiftUIDemo/SwiftUIDemoApp.swift b/SwiftUIDemo/SwiftUIDemo/SwiftUIDemoApp.swift
new file mode 100644
index 0000000..fc44454
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/SwiftUIDemoApp.swift
@@ -0,0 +1,17 @@
+//
+// SwiftUIDemoApp.swift
+// SwiftUIDemo
+//
+// Created by Timothy Moose on 10/5/23.
+//
+
+import SwiftUI
+
+@main
+struct SwiftUIDemoApp: App {
+ var body: some Scene {
+ WindowGroup {
+ DemoView()
+ }
+ }
+}
From 947c4e065409de7cae61e5f70a37f366a65f3ec6 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Fri, 6 Oct 2023 09:46:04 -0500
Subject: [PATCH 15/38] Update SwiftUI comments in README.md
---
README.md | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/README.md b/README.md
index 0cf8e79..8cb208b 100644
--- a/README.md
+++ b/README.md
@@ -12,29 +12,22 @@
## Overview
-SwiftMessages is a very flexible view and view controller presentation library for iOS.
+🔥🔥🔥 **NEW** SwiftUI support added!
-Message views and view controllers can be displayed at the top, bottom, or center of the screen, or behind navigation bars and tab bars. There are interactive dismiss gestures including a fun, physics-based one. Multiple background dimming modes. And a lot more!
+SwiftMessages is a very flexible view and view controller presentation library for UIKit and SwiftUI.
-🔥 Now supports displaying SwiftUI message views 🔥
+Message views and view controllers can be displayed at the top, bottom, or center of the screen, or behind navigation bars and tab bars. There are interactive dismiss gestures including a fun, physics-based one. Multiple background dimming modes. And a lot more!
In addition to the numerous configuration options, SwiftMessages provides several good-looking layouts and themes. But SwiftMessages is also designer-friendly, which means you can fully and easily customize the view:
* Copy one of the included nib files into your project and change it.
* Subclass `MessageView` and add elements, etc.
-* Or just supply an arbitrary instance of `UIView`.
-
-Try exploring [the demo app via appetize.io](http://goo.gl/KXw4nD) to get a feel for the extensive configurability of SwiftMessages.
+* Or just supply an arbitrary instance of `View` or `UIView`.
-
-
-
-
-
## Installation
### Swift Package Manager
@@ -185,7 +178,7 @@ And check out our blog post [Elegant Custom UIViewController Transitioning](http
Any of the built-in SwiftMessages views can be displayed by calling the SwiftMessages APIs from within observable object, a button action closure, etc. However, SwiftMessages can also display your custom SwiftUI views.
-First, define a type that conforms to `MessageViewConvertible`. This will typically be a struct containing the message data:
+The first step is to define a type that conforms to `MessageViewConvertible`. This would typically be a struct containing the message data to display:
````swift
From 691e9bf4656e5e7b47a66220770b5101b502574d Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Fri, 6 Oct 2023 09:47:53 -0500
Subject: [PATCH 16/38] Update changelog
---
CHANGELOG.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a4ec93..fdb8977 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
## 9.0.7
+### Features
+
+* Added support for SwiftUI
+
### Fixes
* #527 Crash while clicking two times to hide the presenting controller
From 188705b897cbc38e3f1e993978b5b7e46906e958 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Fri, 6 Oct 2023 09:55:16 -0500
Subject: [PATCH 17/38] Fix email address
---
SwiftMessages.podspec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index 00b6a81..941a982 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -3,7 +3,7 @@ Pod::Spec.new do |spec|
spec.version = '9.0.7'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
- spec.authors = { 'Timothy Moose' => 'tim@swiftkick.it' }
+ spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }
spec.summary = 'A very flexible message bar for iOS written in Swift.'
spec.source = {:git => 'https://github.com/SwiftKickMobile/SwiftMessages.git', :tag => spec.version}
spec.platform = :ios, '12.0'
From c2bcb351434ae044a486803ad1751b0e10f0d4e1 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Sat, 7 Oct 2023 14:13:34 -0500
Subject: [PATCH 18/38] Address #529
---
CHANGELOG.md | 6 +++++
README.md | 10 +++++++--
SwiftMessages.podspec | 2 +-
.../SwiftUIDemo.xcodeproj/project.pbxproj | 4 ++++
SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift | 11 +++++++---
SwiftUIDemo/SwiftUIDemo/DemoView.swift | 22 -------------------
6 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fdb8977..d17b7a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 9.0.8
+
+### Changes
+
+* #529 Update readme and SwiftUI demo to demostrate how to mask edges.
+
## 9.0.7
### Features
diff --git a/README.md b/README.md
index 8cb208b..10ec0f2 100644
--- a/README.md
+++ b/README.md
@@ -208,8 +208,14 @@ struct DemoMessageView: View {
.padding(30)
.frame(maxWidth: .infinity)
.background(.gray)
- .cornerRadius(15)
- .padding(15)
+ // This makes a tab-style view where the bottom corners are rounded and the view's background
+ // extends to the top edge.
+ .mask(
+ UnevenRoundedRectangle(
+ cornerRadii: .init(bottomLeading: 15, bottomTrailing: 15)
+ )
+ .edgesIgnoringSafeArea(.top)
+ )
}
}
````
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index 941a982..e67d4b0 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '9.0.7'
+ spec.version = '9.0.8'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }
diff --git a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
index 8b289e2..f6c945b 100644
--- a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
+++ b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
@@ -58,6 +58,8 @@
228F7DBD2ACF1E1E006C9644 /* SwiftMessages.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SwiftMessages.xcodeproj; path = ../SwiftMessages.xcodeproj; sourceTree = ""; };
228F7DD42ACF59E4006C9644 /* DemoMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoMessage.swift; sourceTree = ""; };
228F7DD62ACF5C2E006C9644 /* DemoMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoMessageView.swift; sourceTree = ""; };
+ 2291AA492AD1E3EC0084868E /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; };
+ 2291AA4C2AD1E4520084868E /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -75,6 +77,8 @@
228F7DA02ACF17E8006C9644 = {
isa = PBXGroup;
children = (
+ 2291AA4C2AD1E4520084868E /* CHANGELOG.md */,
+ 2291AA492AD1E3EC0084868E /* README.md */,
228F7DAB2ACF17E8006C9644 /* SwiftUIDemo */,
228F7DAA2ACF17E8006C9644 /* Products */,
228F7DC72ACF1E63006C9644 /* Frameworks */,
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift b/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
index cce5058..a299c35 100644
--- a/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
+++ b/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
@@ -28,8 +28,13 @@ struct DemoMessageView: View {
.padding(30)
.frame(maxWidth: .infinity)
.background(.demoMessageBackground)
- .cornerRadius(15)
- .padding(15)
+ // This makes a tab-style view where the bottom corners are rounded and the view's background
+ // extends to the top edge.
+ .mask(
+ UnevenRoundedRectangle(
+ cornerRadii: .init(bottomLeading: 15, bottomTrailing: 15)
+ )
+ .edgesIgnoringSafeArea(.top)
+ )
}
}
-
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoView.swift b/SwiftUIDemo/SwiftUIDemo/DemoView.swift
index e0bcd6c..a6736d8 100644
--- a/SwiftUIDemo/SwiftUIDemo/DemoView.swift
+++ b/SwiftUIDemo/SwiftUIDemo/DemoView.swift
@@ -24,25 +24,3 @@ struct DemoView: View {
#Preview {
DemoView()
}
-
-struct DemoViewx: View {
- var body: some View {
- Button("Show message") {
- let message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
- let messageView = MessageHostingView(message: message)
- SwiftMessages.show(view: messageView)
- }
- }
-}
-
-struct DemoViewy: View {
-
- @State var message: DemoMessage?
-
- var body: some View {
- Button("Show message") {
- message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
- }
- .swiftMessage(message: $message)
- }
-}
From 62e12e138fc3eedf88c7553dd5d98712aa119f40 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Wed, 1 Nov 2023 12:59:03 -0500
Subject: [PATCH 19/38] Couple of fixes
---
CHANGELOG.md | 7 +++
README.md | 10 ++--
SwiftMessages.podspec | 2 +-
SwiftMessages/KeyboardTrackingView.swift | 17 +++++--
SwiftMessages/MessageHostingView.swift | 8 ++++
SwiftUIDemo/SwiftUIDemo/DemoMessage.swift | 3 +-
SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift | 46 +++++++++++++++----
SwiftUIDemo/SwiftUIDemo/DemoView.swift | 26 +++++++++--
8 files changed, 98 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d17b7a8..0f5cc82 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,13 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 9.0.9
+
+### Fixes
+
+* Fix hit testing on SwiftUI views to allow touches around the view's margins to pass through to the underlying view.
+* Update `KeyboardTrackingView` to continue tracking the keyboard even when not installed in the view hierarchy.
+
## 9.0.8
### Changes
diff --git a/README.md b/README.md
index 10ec0f2..5af94cb 100644
--- a/README.md
+++ b/README.md
@@ -206,14 +206,14 @@ struct DemoMessageView: View {
}
.multilineTextAlignment(.leading)
.padding(30)
+ // This makes the message width greedy
.frame(maxWidth: .infinity)
.background(.gray)
- // This makes a tab-style view where the bottom corners are rounded and the view's background
- // extends to the top edge.
+ // This makes a tab-style view where the bottom corners are rounded and
+ // the view's background extends to the top edge.
.mask(
- UnevenRoundedRectangle(
- cornerRadii: .init(bottomLeading: 15, bottomTrailing: 15)
- )
+ UnevenRoundedRectangle(bottomLeadingRadius: 15, bottomTrailingRadius: 15)
+ // This causes the background to extend into the safe area to the screen edge.
.edgesIgnoringSafeArea(.top)
)
}
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index e67d4b0..0e7b79c 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '9.0.8'
+ spec.version = '9.0.9'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }
diff --git a/SwiftMessages/KeyboardTrackingView.swift b/SwiftMessages/KeyboardTrackingView.swift
index 301d969..f3c0ad9 100644
--- a/SwiftMessages/KeyboardTrackingView.swift
+++ b/SwiftMessages/KeyboardTrackingView.swift
@@ -72,6 +72,7 @@ open class KeyboardTrackingView: UIView {
private var isAutomaticallyPaused = false
private var heightConstraint: NSLayoutConstraint!
+ private var lastObservedKeyboardRect: CGRect?
private func postInit() {
translatesAutoresizingMaskIntoConstraints = false
@@ -109,15 +110,19 @@ open class KeyboardTrackingView: UIView {
isAutomaticallyPaused = false
}
+ open override func layoutSubviews() {
+ super.layoutSubviews()
+ heightConstraint.constant = calculateHeightConstant()
+ }
+
private func show(change: Change, _ notification: Notification) {
guard !(isPaused || isAutomaticallyPaused),
let userInfo = (notification as NSNotification).userInfo,
let value = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
willChange(change: change, userInfo: userInfo)
delegate?.keyboardTrackingViewWillChange(change: change, userInfo: userInfo)
- let keyboardRect = value.cgRectValue
- let thisRect = convert(bounds, to: nil)
- let newHeight = max(0, thisRect.maxY - keyboardRect.minY) + topMargin
+ lastObservedKeyboardRect = value.cgRectValue
+ let newHeight = calculateHeightConstant()
guard heightConstraint.constant != newHeight else { return }
animateKeyboardChange(change: change, height: newHeight, userInfo: userInfo)
}
@@ -140,4 +145,10 @@ open class KeyboardTrackingView: UIView {
CATransaction.commit()
}
}
+
+ private func calculateHeightConstant() -> CGFloat {
+ guard let keyboardRect = lastObservedKeyboardRect else { return 0 }
+ let thisRect = convert(bounds, to: nil)
+ return max(0, thisRect.maxY - keyboardRect.minY) + topMargin
+ }
}
diff --git a/SwiftMessages/MessageHostingView.swift b/SwiftMessages/MessageHostingView.swift
index d7bb5f1..489ab96 100644
--- a/SwiftMessages/MessageHostingView.swift
+++ b/SwiftMessages/MessageHostingView.swift
@@ -39,4 +39,12 @@ public class MessageHostingView: BaseView, Identifiable where Content:
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
+
+ public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
+ let view = super.hitTest(point, with: event)
+ // The rendered SwiftUI view isn't a direct child of this hosting view. SwiftUI
+ // inserts another intermediate view that should also ignore touches.
+ if view == self || view?.superview == self { return nil }
+ return view
+ }
}
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoMessage.swift b/SwiftUIDemo/SwiftUIDemo/DemoMessage.swift
index ccc86b6..32624de 100644
--- a/SwiftUIDemo/SwiftUIDemo/DemoMessage.swift
+++ b/SwiftUIDemo/SwiftUIDemo/DemoMessage.swift
@@ -11,12 +11,13 @@ import SwiftMessages
struct DemoMessage: Identifiable {
let title: String
let body: String
+ let style: DemoMessageView.Style
var id: String { title + body }
}
extension DemoMessage: MessageViewConvertible {
func asMessageView() -> DemoMessageView {
- DemoMessageView(message: self)
+ DemoMessageView(message: self, style: style)
}
}
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift b/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
index a299c35..5396302 100644
--- a/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
+++ b/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
@@ -7,11 +7,20 @@
import SwiftUI
+// A card-style message view
struct DemoMessageView: View {
// MARK: - API
+ enum Style {
+ case standard
+ case card
+ case tab
+ }
+
let message: DemoMessage
+ let style: Style
+
// MARK: - Variables
@@ -20,21 +29,42 @@ struct DemoMessageView: View {
// MARK: - Body
var body: some View {
+ switch style {
+ case .standard:
+ content()
+ // Mask the content and extend background into the safe area.
+ .mask {
+ Rectangle()
+ .edgesIgnoringSafeArea(.top)
+ }
+ case .card:
+ content()
+ // Mask the content with a rounded rectangle
+ .mask {
+ RoundedRectangle(cornerRadius: 15)
+ }
+ // External padding around the card
+ .padding(10)
+ case .tab:
+ content()
+ // Mask the content with rounded bottom edge and extend background into the safe area.
+ .mask {
+ UnevenRoundedRectangle(bottomLeadingRadius: 15, bottomTrailingRadius: 15)
+ .edgesIgnoringSafeArea(.top)
+ }
+ }
+ }
+
+ @ViewBuilder private func content() -> some View {
VStack(alignment: .leading) {
Text(message.title).font(.system(size: 20, weight: .bold))
Text(message.body)
}
.multilineTextAlignment(.leading)
+ // Internal padding of the card
.padding(30)
+ // Greedy width
.frame(maxWidth: .infinity)
.background(.demoMessageBackground)
- // This makes a tab-style view where the bottom corners are rounded and the view's background
- // extends to the top edge.
- .mask(
- UnevenRoundedRectangle(
- cornerRadii: .init(bottomLeading: 15, bottomTrailing: 15)
- )
- .edgesIgnoringSafeArea(.top)
- )
}
}
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoView.swift b/SwiftUIDemo/SwiftUIDemo/DemoView.swift
index a6736d8..8f47b7d 100644
--- a/SwiftUIDemo/SwiftUIDemo/DemoView.swift
+++ b/SwiftUIDemo/SwiftUIDemo/DemoView.swift
@@ -13,10 +13,30 @@ struct DemoView: View {
@State var message: DemoMessage?
var body: some View {
- Button("Show message") {
- message = DemoMessage(title: "Demo", body: "This is a sample SwiftUI message! This content should be long enough to wrap.")
+ VStack {
+ Button("Show standard message") {
+ message = DemoMessage(
+ title: "Demo",
+ body: "This is a sample SwiftUI card-style message! This content should be long enough to wrap.",
+ style: .standard
+ )
+ }
+ Button("Show card message") {
+ message = DemoMessage(
+ title: "Demo",
+ body: "This is a sample SwiftUI card-style message! This content should be long enough to wrap.",
+ style: .card
+ )
+ }
+ Button("Show tab message") {
+ message = DemoMessage(
+ title: "Demo",
+ body: "This is a sample SwiftUI card-style message! This content should be long enough to wrap.",
+ style: .tab
+ )
+ }
}
- .buttonBorderShape(.roundedRectangle(radius: 15))
+ .buttonStyle(.bordered)
.swiftMessage(message: $message)
}
}
From 95f65d57f018a18ec352c6bf7fde1a6e3c4550c9 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Sun, 3 Dec 2023 10:41:56 -0600
Subject: [PATCH 20/38] #534 Fix warnings?
---
SwiftMessages/BaseView.swift | 10 +--
.../MarginAdjustable+Extensions.swift | 21 +-----
SwiftMessages/PhysicsAnimation.swift | 4 +-
SwiftMessages/Presenter.swift | 65 ++++++++-----------
SwiftMessages/TopBottomAnimation.swift | 4 +-
5 files changed, 35 insertions(+), 69 deletions(-)
diff --git a/SwiftMessages/BaseView.swift b/SwiftMessages/BaseView.swift
index e5aa7b9..c41d166 100644
--- a/SwiftMessages/BaseView.swift
+++ b/SwiftMessages/BaseView.swift
@@ -280,6 +280,11 @@ open class BaseView: UIView, BackgroundViewable, MarginAdjustable {
private var layoutConstraints: [NSLayoutConstraint] = []
private var regularWidthLayoutConstraints: [NSLayoutConstraint] = []
+
+ open override func layoutSubviews() {
+ super.layoutSubviews()
+ updateShadowPath()
+ }
}
/*
@@ -334,11 +339,6 @@ extension BaseView {
// Update the layer's `shadowPath` without animation
layer.shadowPath = shadowPath }
}
-
- open override func layoutSubviews() {
- super.layoutSubviews()
- updateShadowPath()
- }
}
/*
diff --git a/SwiftMessages/MarginAdjustable+Extensions.swift b/SwiftMessages/MarginAdjustable+Extensions.swift
index b627788..da8f46d 100644
--- a/SwiftMessages/MarginAdjustable+Extensions.swift
+++ b/SwiftMessages/MarginAdjustable+Extensions.swift
@@ -13,25 +13,8 @@ extension MarginAdjustable where Self: UIView {
var layoutMargins: UIEdgeInsets = layoutMarginAdditions
var safeAreaInsets: UIEdgeInsets = {
guard respectSafeArea else { return .zero }
- if #available(iOS 11, *) {
- insetsLayoutMarginsFromSafeArea = false
- return self.safeAreaInsets
- } else {
- #if SWIFTMESSAGES_APP_EXTENSIONS
- let application: UIApplication? = nil
- #else
- let application: UIApplication? = UIApplication.shared
- #endif
- if !context.safeZoneConflicts.isDisjoint(with: [.statusBar]),
- let app = application,
- app.statusBarOrientation == .portrait || app.statusBarOrientation == .portraitUpsideDown {
- let frameInWindow = convert(bounds, to: window)
- let top = max(0, 20 - frameInWindow.minY)
- return UIEdgeInsets(top: top, left: 0, bottom: 0, right: 0)
- } else {
- return .zero
- }
- }
+ insetsLayoutMarginsFromSafeArea = false
+ return self.safeAreaInsets
}()
if !context.safeZoneConflicts.isDisjoint(with: .overStatusBar) {
safeAreaInsets.top = 0
diff --git a/SwiftMessages/PhysicsAnimation.swift b/SwiftMessages/PhysicsAnimation.swift
index 0fb976c..c073fe4 100644
--- a/SwiftMessages/PhysicsAnimation.swift
+++ b/SwiftMessages/PhysicsAnimation.swift
@@ -93,9 +93,7 @@ public class PhysicsAnimation: NSObject, Animator {
guard let adjustable = messageView as? MarginAdjustable & UIView,
let context = context else { return }
adjustable.preservesSuperviewLayoutMargins = false
- if #available(iOS 11, *) {
- adjustable.insetsLayoutMarginsFromSafeArea = false
- }
+ adjustable.insetsLayoutMarginsFromSafeArea = false
adjustable.layoutMargins = adjustable.defaultMarginAdjustment(context: context)
}
diff --git a/SwiftMessages/Presenter.swift b/SwiftMessages/Presenter.swift
index 5a3648b..44f9201 100644
--- a/SwiftMessages/Presenter.swift
+++ b/SwiftMessages/Presenter.swift
@@ -236,7 +236,7 @@ class Presenter: NSObject {
}
private func safeZoneConflicts() -> SafeZoneConflicts {
- guard let window = maskingView.window else { return [] }
+ guard let _ = maskingView.window else { return [] }
let windowLevel: UIWindow.Level = {
if let vc = presentationContext.viewControllerValue() as? WindowViewController {
return vc.config.windowLevel ?? .normal
@@ -253,47 +253,34 @@ class Presenter: NSObject {
if let vc = presentationContext.viewControllerValue() as? UITabBarController { return vc.sm_isVisible(view: vc.tabBar) }
return false
}()
- if #available(iOS 11, *) {
- if windowLevel > .normal {
- // TODO seeing `maskingView.safeAreaInsets.top` value of 20 on
- // iPhone 8 with status bar window level. This seems like an iOS bug since
- // the message view's window is above the status bar. Applying a special rule
- // to allow the animator to revove this amount from the layout margins if needed.
- // This may need to be reworked if any future device has a legitimate 20pt top safe area,
- // such as with a potentially smaller notch.
- if maskingView.safeAreaInsets.top == 20 {
- return [.overStatusBar]
- } else {
- var conflicts: SafeZoneConflicts = []
- if maskingView.safeAreaInsets.top > 0 {
- conflicts.formUnion(.sensorNotch)
- }
- if maskingView.safeAreaInsets.bottom > 0 {
- conflicts.formUnion(.homeIndicator)
- }
- return conflicts
+ if windowLevel > .normal {
+ // TODO seeing `maskingView.safeAreaInsets.top` value of 20 on
+ // iPhone 8 with status bar window level. This seems like an iOS bug since
+ // the message view's window is above the status bar. Applying a special rule
+ // to allow the animator to revove this amount from the layout margins if needed.
+ // This may need to be reworked if any future device has a legitimate 20pt top safe area,
+ // such as with a potentially smaller notch.
+ if maskingView.safeAreaInsets.top == 20 {
+ return [.overStatusBar]
+ } else {
+ var conflicts: SafeZoneConflicts = []
+ if maskingView.safeAreaInsets.top > 0 {
+ conflicts.formUnion(.sensorNotch)
}
+ if maskingView.safeAreaInsets.bottom > 0 {
+ conflicts.formUnion(.homeIndicator)
+ }
+ return conflicts
}
- var conflicts: SafeZoneConflicts = []
- if !underNavigationBar {
- conflicts.formUnion(.sensorNotch)
- }
- if !underTabBar {
- conflicts.formUnion(.homeIndicator)
- }
- return conflicts
- } else {
- #if SWIFTMESSAGES_APP_EXTENSIONS
- return []
- #else
- if UIApplication.shared.isStatusBarHidden { return [] }
- if (windowLevel > UIWindow.Level.normal) || underNavigationBar { return [] }
- let statusBarFrame = UIApplication.shared.statusBarFrame
- let statusBarWindowFrame = window.convert(statusBarFrame, from: nil)
- let statusBarViewFrame = maskingView.convert(statusBarWindowFrame, from: nil)
- return statusBarViewFrame.intersects(maskingView.bounds) ? SafeZoneConflicts.statusBar : []
- #endif
}
+ var conflicts: SafeZoneConflicts = []
+ if !underNavigationBar {
+ conflicts.formUnion(.sensorNotch)
+ }
+ if !underTabBar {
+ conflicts.formUnion(.homeIndicator)
+ }
+ return conflicts
}
private func getPresentationContext() throws -> PresentationContext {
diff --git a/SwiftMessages/TopBottomAnimation.swift b/SwiftMessages/TopBottomAnimation.swift
index 21b0f27..a0d440c 100644
--- a/SwiftMessages/TopBottomAnimation.swift
+++ b/SwiftMessages/TopBottomAnimation.swift
@@ -130,9 +130,7 @@ public class TopBottomAnimation: NSObject, Animator {
guard let adjustable = messageView as? MarginAdjustable & UIView,
let context = context else { return }
adjustable.preservesSuperviewLayoutMargins = false
- if #available(iOS 11, *) {
- adjustable.insetsLayoutMarginsFromSafeArea = false
- }
+ adjustable.insetsLayoutMarginsFromSafeArea = false
var layoutMargins = adjustable.defaultMarginAdjustment(context: context)
switch style {
case .top:
From 633b6e593b5730daf9e682cd21f50764bd1e257c Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Sun, 3 Dec 2023 11:54:25 -0600
Subject: [PATCH 21/38] #535 Remove needless async code
---
Package.swift | 2 +-
SwiftMessages.podspec | 4 +-
SwiftMessages.xcodeproj/project.pbxproj | 16 +-
.../xcschemes/SwiftMessages.xcscheme | 2 +-
SwiftMessages/KeyboardTrackingView.swift | 13 +-
SwiftMessages/Presenter.swift | 2 +
SwiftMessages/SwiftMessageModifier.swift | 2 +-
SwiftMessages/SwiftMessages.swift | 167 +++++++-----------
SwiftMessages/Task+Extensions.swift | 15 ++
9 files changed, 105 insertions(+), 118 deletions(-)
create mode 100644 SwiftMessages/Task+Extensions.swift
diff --git a/Package.swift b/Package.swift
index a0f30e8..a906ba1 100644
--- a/Package.swift
+++ b/Package.swift
@@ -4,7 +4,7 @@ import PackageDescription
let package = Package(
name: "SwiftMessages",
platforms: [
- .iOS("9.0")
+ .iOS("13.0")
],
products: [
.library(name: "SwiftMessages", targets: ["SwiftMessages"]),
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index 0e7b79c..b2b0e4f 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -6,9 +6,9 @@ Pod::Spec.new do |spec|
spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }
spec.summary = 'A very flexible message bar for iOS written in Swift.'
spec.source = {:git => 'https://github.com/SwiftKickMobile/SwiftMessages.git', :tag => spec.version}
- spec.platform = :ios, '12.0'
+ spec.platform = :ios, '13.0'
spec.swift_version = '5.0'
- spec.ios.deployment_target = '12.0'
+ spec.ios.deployment_target = '13.0'
spec.framework = 'UIKit'
spec.requires_arc = true
spec.default_subspec = 'App'
diff --git a/SwiftMessages.xcodeproj/project.pbxproj b/SwiftMessages.xcodeproj/project.pbxproj
index 45809f2..19d5bcd 100644
--- a/SwiftMessages.xcodeproj/project.pbxproj
+++ b/SwiftMessages.xcodeproj/project.pbxproj
@@ -59,6 +59,7 @@
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2061EE480D000E2DDC1 /* Animator.swift */; };
2298C2091EE486E300E2DDC1 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */; };
229F778125FAB1E9008C2ACB /* UIWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */; };
+ 22D3B4562B1CEF76002D8665 /* Task+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22D3B4552B1CEF76002D8665 /* Task+Extensions.swift */; };
22DFC9161EFF30F6001B1CA1 /* CenteredView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22DFC9151EFF30F6001B1CA1 /* CenteredView.xib */; };
22DFC9181F00674E001B1CA1 /* PhysicsPanHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22DFC9171F00674E001B1CA1 /* PhysicsPanHandler.swift */; };
22E01F641E74EC8B00ACE19A /* MaskingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22E01F631E74EC8B00ACE19A /* MaskingView.swift */; };
@@ -151,6 +152,7 @@
2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopBottomAnimation.swift; sourceTree = ""; };
229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIWindow+Extensions.swift"; sourceTree = ""; };
22A2EA6E24EC6CFA00BB2540 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
+ 22D3B4552B1CEF76002D8665 /* Task+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Task+Extensions.swift"; sourceTree = ""; };
22DFC9151EFF30F6001B1CA1 /* CenteredView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = CenteredView.xib; path = Resources/CenteredView.xib; sourceTree = ""; };
22DFC9171F00674E001B1CA1 /* PhysicsPanHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhysicsPanHandler.swift; sourceTree = ""; };
22E01F631E74EC8B00ACE19A /* MaskingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaskingView.swift; sourceTree = ""; };
@@ -220,6 +222,7 @@
220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */,
22774B9F20B5EF2A00813732 /* UIEdgeInsets+Extensions.swift */,
229F778025FAB1E9008C2ACB /* UIWindow+Extensions.swift */,
+ 22D3B4552B1CEF76002D8665 /* Task+Extensions.swift */,
);
name = Extensions;
sourceTree = "";
@@ -453,7 +456,7 @@
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 0730;
- LastUpgradeCheck = 1500;
+ LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "SwiftKick Mobile";
TargetAttributes = {
86B48AEB1D5A41C900063E2B = {
@@ -556,6 +559,7 @@
22F27951210CE25900273E7F /* CornerRoundingView.swift in Sources */,
86BBA9011D5E040600FE8F16 /* PassthroughWindow.swift in Sources */,
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */,
+ 22D3B4562B1CEF76002D8665 /* Task+Extensions.swift in Sources */,
86BBA9031D5E040600FE8F16 /* UIViewController+Extensions.swift in Sources */,
228F7DDF2ACF703A006C9644 /* SwiftMessageModifier.swift in Sources */,
224FB69921153B440081D4DE /* CALayer+Extensions.swift in Sources */,
@@ -609,6 +613,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -655,7 +660,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -668,6 +673,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
@@ -708,7 +714,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
@@ -732,7 +738,7 @@
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
INFOPLIST_FILE = SwiftMessages/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -767,7 +773,7 @@
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
INFOPLIST_FILE = SwiftMessages/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
diff --git a/SwiftMessages.xcodeproj/xcshareddata/xcschemes/SwiftMessages.xcscheme b/SwiftMessages.xcodeproj/xcshareddata/xcschemes/SwiftMessages.xcscheme
index 5c84455..ba0f414 100644
--- a/SwiftMessages.xcodeproj/xcshareddata/xcschemes/SwiftMessages.xcscheme
+++ b/SwiftMessages.xcodeproj/xcshareddata/xcschemes/SwiftMessages.xcscheme
@@ -1,6 +1,6 @@
)
case view(_: Weak)
diff --git a/SwiftMessages/SwiftMessageModifier.swift b/SwiftMessages/SwiftMessageModifier.swift
index 479b6d9..9974e8b 100644
--- a/SwiftMessages/SwiftMessageModifier.swift
+++ b/SwiftMessages/SwiftMessageModifier.swift
@@ -47,7 +47,7 @@ private struct SwiftMessageModifier: ViewModifier where Message: Messag
content
.onChange(of: message) { _ in
if let message {
- let show: (SwiftMessages.Config, UIView) -> Void = swiftMessages?.show(config:view:) ?? SwiftMessages.show(config:view:)
+ let show: @MainActor (SwiftMessages.Config, UIView) -> Void = swiftMessages?.show(config:view:) ?? SwiftMessages.show(config:view:)
let view = MessageHostingView(message: message)
var config = config ?? swiftMessages?.defaultConfig ?? SwiftMessages.defaultConfig
config.eventListeners.append { event in
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index 395bc0a..52244ef 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -8,6 +8,7 @@
import UIKit
+@MainActor
private let globalInstance = SwiftMessages()
/**
@@ -15,6 +16,7 @@ private let globalInstance = SwiftMessages()
It behaves like a queue, only showing one message at a time. Message views that
adopt the `Identifiable` protocol (as `MessageView` does) will have duplicates removed.
*/
+@MainActor
open class SwiftMessages {
/**
@@ -396,9 +398,7 @@ open class SwiftMessages {
*/
open func show(config: Config, view: UIView) {
let presenter = Presenter(config: config, view: view, delegate: self)
- messageQueue.sync {
- enqueue(presenter: presenter)
- }
+ enqueue(presenter: presenter)
}
/**
@@ -425,11 +425,11 @@ open class SwiftMessages {
- Parameter config: The configuration options.
- Parameter viewProvider: A block that returns the view to be displayed.
*/
- open func show(config: Config, viewProvider: @escaping ViewProvider) {
- DispatchQueue.main.async { [weak self] in
- guard let strongSelf = self else { return }
+ nonisolated open func show(config: Config, viewProvider: @escaping ViewProvider) {
+ Task { @MainActor [weak self] in
+ guard let self else { return }
let view = viewProvider()
- strongSelf.show(config: config, view: view)
+ self.show(config: config, view: view)
}
}
@@ -451,9 +451,7 @@ open class SwiftMessages {
Hide the current message being displayed by animating it away.
*/
open func hide(animated: Bool = true) {
- messageQueue.sync {
- hideCurrent(animated: animated)
- }
+ hideCurrent(animated: animated)
}
/**
@@ -461,12 +459,10 @@ open class SwiftMessages {
clear the message queue.
*/
open func hideAll() {
- messageQueue.sync {
- queue.removeAll()
- delays.removeAll()
- counts.removeAll()
- hideCurrent()
- }
+ queue.removeAll()
+ delays.removeAll()
+ counts.removeAll()
+ hideCurrent()
}
/**
@@ -476,14 +472,12 @@ open class SwiftMessages {
- Parameter id: The identifier of the message to remove.
*/
open func hide(id: String) {
- messageQueue.sync {
- if id == _current?.id {
- hideCurrent()
- }
- queue = queue.filter { $0.id != id }
- delays.remove(id: id)
- counts[id] = nil
+ if id == _current?.id {
+ hideCurrent()
}
+ queue = queue.filter { $0.id != id }
+ delays.remove(id: id)
+ counts[id] = nil
}
/**
@@ -492,21 +486,19 @@ open class SwiftMessages {
shown from multiple code paths to ensure that all paths are ready to hide.
*/
open func hideCounted(id: String) {
- messageQueue.sync {
- if let count = counts[id] {
- if count < 2 {
- counts[id] = nil
- } else {
- counts[id] = count - 1
- return
- }
- }
- if id == _current?.id {
- hideCurrent()
+ if let count = counts[id] {
+ if count < 2 {
+ counts[id] = nil
+ } else {
+ counts[id] = count - 1
+ return
}
- queue = queue.filter { $0.id != id }
- delays.remove(id: id)
}
+ if id == _current?.id {
+ hideCurrent()
+ }
+ queue = queue.filter { $0.id != id }
+ delays.remove(id: id)
}
/**
@@ -538,6 +530,7 @@ open class SwiftMessages {
open var pauseBetweenMessages: TimeInterval = 0.5
/// Type for keeping track of delayed presentations
+ @MainActor
fileprivate class Delays {
fileprivate func add(presenter: Presenter) {
@@ -563,20 +556,17 @@ open class SwiftMessages {
}
func show(presenter: Presenter) {
- messageQueue.sync {
- enqueue(presenter: presenter)
- }
+ enqueue(presenter: presenter)
}
- fileprivate let messageQueue = DispatchQueue(label: "it.swiftkick.SwiftMessages", attributes: [])
fileprivate var queue: [Presenter] = []
fileprivate var delays = Delays()
fileprivate var counts: [String : Int] = [:]
fileprivate var _current: Presenter? = nil {
didSet {
if oldValue != nil {
- let delayTime = DispatchTime.now() + pauseBetweenMessages
- messageQueue.asyncAfter(deadline: delayTime) { [weak self] in
+ Task { [weak self] in
+ try? await Task.sleep(seconds: self?.pauseBetweenMessages ?? 0)
self?.dequeueNext()
}
}
@@ -598,9 +588,10 @@ open class SwiftMessages {
}
if let delay = presenter.delayShow {
delays.add(presenter: presenter)
- messageQueue.asyncAfter(deadline: .now() + delay) { [weak self] in
+ Task { [weak self] in
+ try? await Task.sleep(seconds: delay)
// Don't enqueue if the view has been hidden during the delay window.
- guard let strongSelf = self, strongSelf.delays.remove(presenter: presenter) else { return }
+ guard let self, self.delays.remove(presenter: presenter) else { return }
doEnqueue()
}
} else {
@@ -618,26 +609,19 @@ open class SwiftMessages {
// block on animation completion.
self.autohideToken = current
current.showDate = CACurrentMediaTime()
- DispatchQueue.main.async { [weak self] in
- guard let strongSelf = self else { return }
- do {
- try current.show { completed in
- guard let strongSelf = self else { return }
- guard completed else {
- strongSelf.messageQueue.sync {
- strongSelf.internalHide(presenter: current)
- }
- return
- }
- if current === strongSelf.autohideToken {
- strongSelf.queueAutoHide()
- }
+ do {
+ try current.show { [weak self] completed in
+ guard let self else { return }
+ guard completed else {
+ self.internalHide(presenter: current)
+ return
}
- } catch {
- strongSelf.messageQueue.sync {
- strongSelf._current = nil
+ if current === self.autohideToken {
+ self.queueAutoHide()
}
}
+ } catch {
+ _current = nil
}
}
@@ -654,16 +638,15 @@ open class SwiftMessages {
guard let current = _current, !current.isHiding else { return }
let action = { [weak self] in
current.hide(animated: animated) { (completed) in
- guard completed, let strongSelf = self else { return }
- strongSelf.messageQueue.sync {
- guard strongSelf._current === current else { return }
- strongSelf.counts[current.id] = nil
- strongSelf._current = nil
- }
+ guard completed, let self else { return }
+ guard self._current === current else { return }
+ self.counts[current.id] = nil
+ self._current = nil
}
}
let delay = current.delayHide ?? 0
- DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
+ Task {
+ try? await Task.sleep(seconds: delay)
action()
}
}
@@ -674,18 +657,20 @@ open class SwiftMessages {
guard let current = _current else { return }
autohideToken = current
if let pauseDuration = current.pauseDuration {
- let delayTime = DispatchTime.now() + pauseDuration
- messageQueue.asyncAfter(deadline: delayTime, execute: {
+ Task { [weak self] in
+ try? await Task.sleep(seconds: pauseDuration)
// Make sure we've still got a green light to auto-hide.
- if self.autohideToken !== current { return }
+ guard let self, self.autohideToken !== current else { return }
self.internalHide(presenter: current)
- })
+ }
}
}
deinit {
- // Prevent orphaned messages
- hideCurrent()
+ guard let current = _current else { return }
+ Task { @MainActor [current] in
+ current.hide(animated: true) { _ in }
+ }
}
}
@@ -701,11 +686,7 @@ extension SwiftMessages {
- Returns: The view of type `T` if it is currently being shown or hidden.
*/
public func current() -> T? {
- var view: T?
- messageQueue.sync {
- view = _current?.view as? T
- }
- return view
+ _current?.view as? T
}
/**
@@ -715,13 +696,7 @@ extension SwiftMessages {
- Returns: The view with matching id if currently being shown or hidden.
*/
public func current(id: String) -> T? {
- var view: T?
- messageQueue.sync {
- if let current = _current, current.id == id {
- view = current.view as? T
- }
- }
- return view
+ _current?.id == id ? _current?.view as? T : nil
}
/**
@@ -731,13 +706,7 @@ extension SwiftMessages {
- Returns: The view with matching id if currently queued to be shown.
*/
public func queued(id: String) -> T? {
- var view: T?
- messageQueue.sync {
- if let queued = queue.first(where: { $0.id == id }) {
- view = queued.view as? T
- }
- }
- return view
+ queue.first { $0.id == id }?.view as? T
}
/**
@@ -759,16 +728,12 @@ extension SwiftMessages {
extension SwiftMessages: PresenterDelegate {
func hide(presenter: Presenter) {
- messageQueue.sync {
- self.internalHide(presenter: presenter)
- }
+ self.internalHide(presenter: presenter)
}
public func hide(animator: Animator) {
- messageQueue.sync {
- guard let presenter = self.presenter(forAnimator: animator) else { return }
- self.internalHide(presenter: presenter)
- }
+ guard let presenter = self.presenter(forAnimator: animator) else { return }
+ self.internalHide(presenter: presenter)
}
public func panStarted(animator: Animator) {
@@ -898,7 +863,7 @@ extension SwiftMessages {
globalInstance.show(viewProvider: viewProvider)
}
- public static func show(config: Config, viewProvider: @escaping ViewProvider) {
+ nonisolated public static func show(config: Config, viewProvider: @escaping ViewProvider) {
globalInstance.show(config: config, viewProvider: viewProvider)
}
diff --git a/SwiftMessages/Task+Extensions.swift b/SwiftMessages/Task+Extensions.swift
new file mode 100644
index 0000000..9d6f1c3
--- /dev/null
+++ b/SwiftMessages/Task+Extensions.swift
@@ -0,0 +1,15 @@
+//
+// Task+Extensions.swift
+// SwiftMessages
+//
+// Created by Timothy Moose on 12/3/23.
+// Copyright © 2023 SwiftKick Mobile. All rights reserved.
+//
+
+import Foundation
+
+extension Task where Success == Never, Failure == Never {
+ static func sleep(seconds: TimeInterval) async throws {
+ try await sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
+ }
+}
From 5ff2cb30766d7b153bb60b29338e095a0cfd3e38 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Sun, 3 Dec 2023 12:03:14 -0600
Subject: [PATCH 22/38] Remove a couple of more usages of dispatch queues
---
SwiftMessages/Animator.swift | 1 +
SwiftMessages/PhysicsAnimation.swift | 1 +
SwiftMessages/PhysicsPanHandler.swift | 5 ++++-
SwiftMessages/SwiftMessagesSegue.swift | 3 ++-
4 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/SwiftMessages/Animator.swift b/SwiftMessages/Animator.swift
index 8207406..346ce2f 100644
--- a/SwiftMessages/Animator.swift
+++ b/SwiftMessages/Animator.swift
@@ -58,6 +58,7 @@ public class AnimationContext {
}
}
+@MainActor
public protocol Animator: AnyObject {
/// Adopting classes should declare as `weak`.
diff --git a/SwiftMessages/PhysicsAnimation.swift b/SwiftMessages/PhysicsAnimation.swift
index c073fe4..5f5ecaf 100644
--- a/SwiftMessages/PhysicsAnimation.swift
+++ b/SwiftMessages/PhysicsAnimation.swift
@@ -8,6 +8,7 @@
import UIKit
+@MainActor
public class PhysicsAnimation: NSObject, Animator {
public enum Placement {
diff --git a/SwiftMessages/PhysicsPanHandler.swift b/SwiftMessages/PhysicsPanHandler.swift
index da82fc1..e381d22 100644
--- a/SwiftMessages/PhysicsPanHandler.swift
+++ b/SwiftMessages/PhysicsPanHandler.swift
@@ -8,6 +8,7 @@
import UIKit
+@MainActor
open class PhysicsPanHandler {
public var hideDelay: TimeInterval = 0.2
@@ -17,6 +18,7 @@ open class PhysicsPanHandler {
var time: CFAbsoluteTime
}
+ @MainActor
public final class State {
weak var messageView: UIView?
@@ -127,7 +129,8 @@ open class PhysicsPanHandler {
let frame = containerView.convert(view.bounds, from: view)
if !containerView.bounds.intersects(frame) {
self.isOffScreen = true
- DispatchQueue.main.asyncAfter(deadline: .now() + self.hideDelay) {
+ Task {
+ try? await Task.sleep(seconds: self.hideDelay)
animator.delegate?.hide(animator: animator)
}
}
diff --git a/SwiftMessages/SwiftMessagesSegue.swift b/SwiftMessages/SwiftMessagesSegue.swift
index cd17eec..35687e1 100644
--- a/SwiftMessages/SwiftMessagesSegue.swift
+++ b/SwiftMessages/SwiftMessagesSegue.swift
@@ -228,7 +228,8 @@ open class SwiftMessagesSegue: UIStoryboardSegue {
/// is removed without first dismissing. This monitor handles that scenario by setting `self.selfRetainer = nil` if
/// the presenting view controller is no longer in the heirarchy.
private func startReleaseMonitor() {
- DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
+ Task { @MainActor [weak self] in
+ try? await Task.sleep(seconds: 2)
guard let self = self else { return }
switch self.source.view.window {
case .none: self.selfRetainer = nil
From f3555f04126e93af1bcc5c64fa351bfb38d6740c Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Sun, 3 Dec 2023 12:17:07 -0600
Subject: [PATCH 23/38] Fix typo
---
SwiftMessages/SwiftMessages.swift | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index 52244ef..1245f06 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -651,7 +651,7 @@ open class SwiftMessages {
}
}
- fileprivate weak var autohideToken: AnyObject?
+ fileprivate weak var autohideToken: Presenter?
fileprivate func queueAutoHide() {
guard let current = _current else { return }
@@ -660,7 +660,7 @@ open class SwiftMessages {
Task { [weak self] in
try? await Task.sleep(seconds: pauseDuration)
// Make sure we've still got a green light to auto-hide.
- guard let self, self.autohideToken !== current else { return }
+ guard let self, self.autohideToken == current else { return }
self.internalHide(presenter: current)
}
}
From e70fb07baae07e3dca3da2ce7a8d497bfd472b20 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Mon, 15 Jan 2024 15:20:12 -0600
Subject: [PATCH 24/38] Add sheet like variation on swiftMessage modifier
---
CHANGELOG.md | 12 +++
README.md | 47 +++++++----
SwiftMessages.podspec | 2 +-
SwiftMessages/MessageHostingView.swift | 11 ++-
SwiftMessages/SwiftMessageModifier.swift | 41 ++++++++--
.../SwiftUIDemo.xcodeproj/project.pbxproj | 4 +
SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift | 2 +-
.../DemoMessageWithButtonView.swift | 77 +++++++++++++++++++
SwiftUIDemo/SwiftUIDemo/DemoView.swift | 19 +++++
9 files changed, 190 insertions(+), 25 deletions(-)
create mode 100644 SwiftUIDemo/SwiftUIDemo/DemoMessageWithButtonView.swift
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0f5cc82..6031c13 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,18 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 9.0.10
+
+### Features
+
+* Add a `.sheet()` like variation to the `.swiftMessage()` modifier that takes a view builder. This provides more flexibility for constructing message views.
+
+### Fixes
+
+* #535 window being accessed from background thread when dequeueNext is called
+* #534 Xcode warnings in two swift files
+* #533 How do I show a message that appears above the keyboard, when the keyboard is already visible?
+
## 9.0.9
### Fixes
diff --git a/README.md b/README.md
index 5af94cb..6a6f5af 100644
--- a/README.md
+++ b/README.md
@@ -178,8 +178,7 @@ And check out our blog post [Elegant Custom UIViewController Transitioning](http
Any of the built-in SwiftMessages views can be displayed by calling the SwiftMessages APIs from within observable object, a button action closure, etc. However, SwiftMessages can also display your custom SwiftUI views.
-The first step is to define a type that conforms to `MessageViewConvertible`. This would typically be a struct containing the message data to display:
-
+Take the following message view and companion data model:
````swift
struct DemoMessage: Identifiable {
@@ -189,12 +188,6 @@ struct DemoMessage: Identifiable {
var id: String { title + body }
}
-extension DemoMessage: MessageViewConvertible {
- func asMessageView() -> DemoMessageView {
- DemoMessageView(message: self)
- }
-}
-
struct DemoMessageView: View {
let message: DemoMessage
@@ -212,7 +205,7 @@ struct DemoMessageView: View {
// This makes a tab-style view where the bottom corners are rounded and
// the view's background extends to the top edge.
.mask(
- UnevenRoundedRectangle(bottomLeadingRadius: 15, bottomTrailingRadius: 15)
+ UnevenRoundedRectangle(bottomLeadingRadius: 15, bottomTrailingRadius: 15)
// This causes the background to extend into the safe area to the screen edge.
.edgesIgnoringSafeArea(.top)
)
@@ -220,14 +213,14 @@ struct DemoMessageView: View {
}
````
-The SwiftUI message view can be displayed just like any other UIKit message by using `MessageHostingView`:
+You can show it from a button action, view model or other similar context like:
````swift
struct DemoView: View {
var body: some View {
Button("Show message") {
let message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
- let messageView = MessageHostingView(message: message)
+ let messageView = MessageHostingView(id: message.id, content: DemoMessageView(message: message)
SwiftMessages.show(view: messageView)
}
}
@@ -245,12 +238,40 @@ struct DemoView: View {
Button("Show message") {
message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
}
- .swiftMessage(message: $message)
+ .swiftMessage(message: $message) { message in
+ DemoMessageView(message: message)
+ }
}
}
````
-This technique may be more SwiftUI-like, but it doesn't offer the full capability of SwiftMessages, such as explicitly hiding messages by their ID. It is totally reasonable to use a combination of both approaches.
+This is very similar to the `.sheet()` modifier. However, it doesn't expose all of the features of SwiftMessages, such as explicitly hiding messages by ID. It is totally reasonable to use a combination of both approaches.
+
+If your message views are purely data-driven and don't require delegates, callbacks, etc., there is a slightly simplified variation on `swiftMessage()` that doesn't require a view builder. Instead, your data model should conform to `MessageViewConvertible`.
+
+````swift
+extension DemoMessage: MessageViewConvertible {
+ func asMessageView() -> DemoMessageView {
+ DemoMessageView(message: self)
+ }
+}
+````
+
+Then you can drop the view builder when calling `swiftMessage()`:
+
+````swift
+struct DemoView: View {
+
+ @State var message: DemoMessage?
+
+ var body: some View {
+ Button("Show message") {
+ message = DemoMessage(title: "Demo", body: "SwiftUI forever!")
+ }
+ .swiftMessage(message: $message)
+ }
+}
+````
Try it out in the SwiftUI demo app!
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index b2b0e4f..8042309 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '9.0.9'
+ spec.version = '9.0.10'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }
diff --git a/SwiftMessages/MessageHostingView.swift b/SwiftMessages/MessageHostingView.swift
index 489ab96..b295669 100644
--- a/SwiftMessages/MessageHostingView.swift
+++ b/SwiftMessages/MessageHostingView.swift
@@ -16,10 +16,9 @@ public class MessageHostingView: BaseView, Identifiable where Content:
public let id: String
- public init(message: Message) where Message: MessageViewConvertible, Message.Content == Content {
- let messageView: Content = message.asMessageView()
- hostVC = UIHostingController(rootView: messageView)
- id = message.id
+ public init(id: String, content: Content) {
+ hostVC = UIHostingController(rootView: content)
+ self.id = id
super.init(frame: .zero)
hostVC.loadViewIfNeeded()
installContentView(hostVC.view)
@@ -27,6 +26,10 @@ public class MessageHostingView: BaseView, Identifiable where Content:
hostVC.view.backgroundColor = .clear
}
+ convenience public init(message: Message) where Message: MessageViewConvertible, Message.Content == Content {
+ self.init(id: message.id, content: message.asMessageView() )
+ }
+
// MARK: - Constants
// MARK: - Variables
diff --git a/SwiftMessages/SwiftMessageModifier.swift b/SwiftMessages/SwiftMessageModifier.swift
index 9974e8b..56f40f2 100644
--- a/SwiftMessages/SwiftMessageModifier.swift
+++ b/SwiftMessages/SwiftMessageModifier.swift
@@ -9,28 +9,56 @@ import SwiftUI
@available(iOS 14.0, *)
public extension View {
- /// A state-based modifier for displaying a message.
+ /// A state-based modifier for displaying a message when `Message` does not conform to `MessageViewConvertible`. This variant is more flexible and
+ /// should be used if the message view can't be represented as pure data, such as if it requires a delegate, has callbacks, etc.
+ func swiftMessage(
+ message: Binding,
+ config: SwiftMessages.Config? = nil,
+ swiftMessages: SwiftMessages? = nil,
+ @ViewBuilder messageContent: @escaping (Message) -> MessageContent
+ ) -> some View where Message: Equatable & Identifiable, MessageContent: View {
+ modifier(SwiftMessageModifier(message: message, config: config, swiftMessages: swiftMessages, messageContent: messageContent))
+ }
+
+ /// A state-based modifier for displaying a message when `Message` conforms to `MessageViewConvertible`. This variant should be used if the message
+ /// view can be represented as pure data. If the message requires a delegate, has callbacks, etc., consider using the variant that takes a message view builder.
func swiftMessage(
message: Binding,
config: SwiftMessages.Config? = nil,
swiftMessages: SwiftMessages? = nil
) -> some View where Message: MessageViewConvertible {
- modifier(SwiftMessageModifier(message: message, config: config, swiftMessages: swiftMessages))
+ swiftMessage(message: message, config: config, swiftMessages: swiftMessages) { content in
+ content.asMessageView()
+ }
}
}
@available(iOS 14.0, *)
-private struct SwiftMessageModifier: ViewModifier where Message: MessageViewConvertible {
+private struct SwiftMessageModifier: ViewModifier where Message: Equatable & Identifiable, MessageContent: View {
+
// MARK: - API
fileprivate init(
message: Binding,
config: SwiftMessages.Config? = nil,
- swiftMessages: SwiftMessages? = nil
+ swiftMessages: SwiftMessages? = nil,
+ @ViewBuilder messageContent: @escaping (Message) -> MessageContent
) {
_message = message
self.config = config
self.swiftMessages = swiftMessages
+ self.messageContent = messageContent
+ }
+
+ fileprivate init(
+ message: Binding,
+ config: SwiftMessages.Config? = nil,
+ swiftMessages: SwiftMessages? = nil
+ ) where Message: MessageViewConvertible, Message.Content == MessageContent {
+ _message = message
+ self.config = config
+ self.swiftMessages = swiftMessages
+ self.messageContent = { $0.asMessageView() }
}
// MARK: - Constants
@@ -40,15 +68,16 @@ private struct SwiftMessageModifier: ViewModifier where Message: Messag
@Binding private var message: Message?
private let config: SwiftMessages.Config?
private let swiftMessages: SwiftMessages?
+ @ViewBuilder private let messageContent: (Message) -> MessageContent
// MARK: - Body
func body(content: Content) -> some View {
content
- .onChange(of: message) { _ in
+ .onChange(of: message) { message in
if let message {
let show: @MainActor (SwiftMessages.Config, UIView) -> Void = swiftMessages?.show(config:view:) ?? SwiftMessages.show(config:view:)
- let view = MessageHostingView(message: message)
+ let view = MessageHostingView(id: message.id, content: messageContent(message))
var config = config ?? swiftMessages?.defaultConfig ?? SwiftMessages.defaultConfig
config.eventListeners.append { event in
if case .didHide = event, event.id == self.message?.id {
diff --git a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
index f6c945b..790676b 100644
--- a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
+++ b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 22549DC02B55CFE8005E3E21 /* DemoMessageWithButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22549DBF2B55CFE8005E3E21 /* DemoMessageWithButtonView.swift */; };
228F7DAD2ACF17E8006C9644 /* SwiftUIDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DAC2ACF17E8006C9644 /* SwiftUIDemoApp.swift */; };
228F7DAF2ACF17E8006C9644 /* DemoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DAE2ACF17E8006C9644 /* DemoView.swift */; };
228F7DB12ACF17E9006C9644 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 228F7DB02ACF17E9006C9644 /* Assets.xcassets */; };
@@ -49,6 +50,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 22549DBF2B55CFE8005E3E21 /* DemoMessageWithButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoMessageWithButtonView.swift; sourceTree = ""; };
228F7DA92ACF17E8006C9644 /* SwiftUIDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUIDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
228F7DAC2ACF17E8006C9644 /* SwiftUIDemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIDemoApp.swift; sourceTree = ""; };
228F7DAE2ACF17E8006C9644 /* DemoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoView.swift; sourceTree = ""; };
@@ -102,6 +104,7 @@
228F7DAE2ACF17E8006C9644 /* DemoView.swift */,
228F7DD42ACF59E4006C9644 /* DemoMessage.swift */,
228F7DD62ACF5C2E006C9644 /* DemoMessageView.swift */,
+ 22549DBF2B55CFE8005E3E21 /* DemoMessageWithButtonView.swift */,
228F7DB02ACF17E9006C9644 /* Assets.xcassets */,
228F7DB22ACF17E9006C9644 /* Preview Content */,
);
@@ -230,6 +233,7 @@
228F7DD72ACF5C2E006C9644 /* DemoMessageView.swift in Sources */,
228F7DAF2ACF17E8006C9644 /* DemoView.swift in Sources */,
228F7DAD2ACF17E8006C9644 /* SwiftUIDemoApp.swift in Sources */,
+ 22549DC02B55CFE8005E3E21 /* DemoMessageWithButtonView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift b/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
index 5396302..11cf961 100644
--- a/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
+++ b/SwiftUIDemo/SwiftUIDemo/DemoMessageView.swift
@@ -7,7 +7,7 @@
import SwiftUI
-// A card-style message view
+// A message view with a title and message.
struct DemoMessageView: View {
// MARK: - API
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoMessageWithButtonView.swift b/SwiftUIDemo/SwiftUIDemo/DemoMessageWithButtonView.swift
new file mode 100644
index 0000000..e74172e
--- /dev/null
+++ b/SwiftUIDemo/SwiftUIDemo/DemoMessageWithButtonView.swift
@@ -0,0 +1,77 @@
+//
+// DemoMessageWithButtonView.swift
+// SwiftUIDemo
+//
+// Created by Timothy Moose on 1/15/24.
+//
+
+import SwiftUI
+
+// A message view with a title, message and button.
+struct DemoMessageWithButtonView: View where Button: View {
+
+ // MARK: - API
+
+ enum Style {
+ case standard
+ case card
+ case tab
+ }
+
+ init(message: DemoMessage, style: Style, @ViewBuilder button: @escaping () -> Button) {
+ self.message = message
+ self.style = style
+ self.button = button
+ }
+
+ // MARK: - Variables
+
+ let message: DemoMessage
+ let style: Style
+ @ViewBuilder let button: () -> Button
+
+ // MARK: - Constants
+
+ // MARK: - Body
+
+ var body: some View {
+ switch style {
+ case .standard:
+ content()
+ // Mask the content and extend background into the safe area.
+ .mask {
+ Rectangle()
+ .edgesIgnoringSafeArea(.top)
+ }
+ case .card:
+ content()
+ // Mask the content with a rounded rectangle
+ .mask {
+ RoundedRectangle(cornerRadius: 15)
+ }
+ // External padding around the card
+ .padding(10)
+ case .tab:
+ content()
+ // Mask the content with rounded bottom edge and extend background into the safe area.
+ .mask {
+ UnevenRoundedRectangle(bottomLeadingRadius: 15, bottomTrailingRadius: 15)
+ .edgesIgnoringSafeArea(.top)
+ }
+ }
+ }
+
+ @ViewBuilder private func content() -> some View {
+ VStack() {
+ Text(message.title).font(.system(size: 20, weight: .bold))
+ Text(message.body)
+ button()
+ }
+ .multilineTextAlignment(.center)
+ // Internal padding of the card
+ .padding(30)
+ // Greedy width
+ .frame(maxWidth: .infinity)
+ .background(.demoMessageBackground)
+ }
+}
diff --git a/SwiftUIDemo/SwiftUIDemo/DemoView.swift b/SwiftUIDemo/SwiftUIDemo/DemoView.swift
index 8f47b7d..b6562cf 100644
--- a/SwiftUIDemo/SwiftUIDemo/DemoView.swift
+++ b/SwiftUIDemo/SwiftUIDemo/DemoView.swift
@@ -10,8 +10,12 @@ import SwiftMessages
struct DemoView: View {
+ /// Demonstrates purely data-driven message presentation.
@State var message: DemoMessage?
+ /// Demonstrates message presentation with a view builder.
+ @State var messageWithButton: DemoMessage?
+
var body: some View {
VStack {
Button("Show standard message") {
@@ -35,9 +39,24 @@ struct DemoView: View {
style: .tab
)
}
+ Button("Show message with button") {
+ messageWithButton = DemoMessage(
+ title: "Demo",
+ body: "This message view has a button was constructed with a view builder.",
+ style: .card
+ )
+ }
}
.buttonStyle(.bordered)
.swiftMessage(message: $message)
+ .swiftMessage(message: $messageWithButton) { message in
+ DemoMessageWithButtonView(message: message, style: .card) {
+ Button("Tap Me") {
+ print("Tap")
+ }
+ .buttonStyle(.bordered)
+ }
+ }
}
}
From eb9591af8c3ad4964c2cb389e485583e7a632a6f Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Mon, 22 Jan 2024 15:46:30 -0600
Subject: [PATCH 25/38] Fix SwiftUI hang
---
SwiftMessages/KeyboardTrackingView.swift | 17 ++++++-----------
SwiftMessages/MessageHostingView.swift | 15 ++++++++++++++-
2 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/SwiftMessages/KeyboardTrackingView.swift b/SwiftMessages/KeyboardTrackingView.swift
index 946426b..173af17 100644
--- a/SwiftMessages/KeyboardTrackingView.swift
+++ b/SwiftMessages/KeyboardTrackingView.swift
@@ -128,20 +128,15 @@ open class KeyboardTrackingView: UIView {
}
private func animateKeyboardChange(change: Change, height: CGFloat, userInfo: [AnyHashable: Any]) {
- self.heightConstraint.constant = height
- if let durationNumber = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber,
- let curveNumber = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber {
- CATransaction.begin()
- CATransaction.setCompletionBlock {
- self.didChange(change: change, userInfo: userInfo)
- self.delegate?.keyboardTrackingViewDidChange(change: change, userInfo: userInfo)
- }
- let curve = UIView.AnimationCurve(rawValue: curveNumber.intValue) ?? .easeInOut
- let animation = UIViewPropertyAnimator(duration: durationNumber.doubleValue, curve: curve) {
+ if let durationNumber = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber {
+ UIView.animate(withDuration: durationNumber.doubleValue, delay: 0, options: .curveEaseInOut, animations: {
+ self.heightConstraint.constant = height
self.updateConstraintsIfNeeded()
self.superview?.layoutIfNeeded()
+ }) { completed in
+ self.didChange(change: change, userInfo: userInfo)
+ self.delegate?.keyboardTrackingViewDidChange(change: change, userInfo: userInfo)
}
- animation.startAnimation()
}
}
diff --git a/SwiftMessages/MessageHostingView.swift b/SwiftMessages/MessageHostingView.swift
index b295669..b4634d9 100644
--- a/SwiftMessages/MessageHostingView.swift
+++ b/SwiftMessages/MessageHostingView.swift
@@ -10,7 +10,7 @@ import UIKit
/// A rudimentary hosting view for SwiftUI messages.
@available(iOS 14.0, *)
-public class MessageHostingView: BaseView, Identifiable where Content: View {
+public class MessageHostingView: UIView, Identifiable where Content: View {
// MARK: - API
@@ -50,4 +50,17 @@ public class MessageHostingView: BaseView, Identifiable where Content:
if view == self || view?.superview == self { return nil }
return view
}
+
+ // MARK: - Configuration
+
+ private func installContentView(_ contentView: UIView) {
+ contentView.translatesAutoresizingMaskIntoConstraints = false
+ addSubview(contentView)
+ NSLayoutConstraint.activate([
+ contentView.topAnchor.constraint(equalTo: topAnchor),
+ contentView.bottomAnchor.constraint(equalTo: bottomAnchor),
+ contentView.leftAnchor.constraint(equalTo: leftAnchor),
+ contentView.rightAnchor.constraint(equalTo: rightAnchor),
+ ])
+ }
}
From 262e15f870f64e7a71a2b5137b51d7e480282c6c Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Mon, 22 Jan 2024 18:34:08 -0600
Subject: [PATCH 26/38] Update changelog
---
CHANGELOG.md | 9 +++++++--
SwiftMessages.podspec | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6031c13..c068572 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,16 @@
# Change Log
All notable changes to this project will be documented in this file.
-## 9.0.10
+## 10.0.0
### Features
-* Add a `.sheet()` like variation to the `.swiftMessage()` modifier that takes a view builder. This provides more flexibility for constructing message views.
+* Add a variation on the `.swiftMessage()` modifier that takes a view builder instead of requiring that the bound value conform to `MessageViewConvertible`. This syntax is more similar to the familiar `sheet()` modifier syntax and provides more flexibility for constructing message views.
+
+### Changes
+
+* Use `@MainActor` to ensure that SwiftMessages is not called from a background queue.
+* Bump minimum deployment target to iOS 13.
### Fixes
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index 8042309..6d1a842 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '9.0.10'
+ spec.version = '10.0.0'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }
From e2b1254a973dd954663ff7aa2d8b9abff8dc01da Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Tue, 23 Jan 2024 10:42:23 -0600
Subject: [PATCH 27/38] Fix SwiftUI handling of the message binding
---
SwiftMessages/SwiftMessageModifier.swift | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/SwiftMessages/SwiftMessageModifier.swift b/SwiftMessages/SwiftMessageModifier.swift
index 56f40f2..3cab498 100644
--- a/SwiftMessages/SwiftMessageModifier.swift
+++ b/SwiftMessages/SwiftMessageModifier.swift
@@ -75,8 +75,10 @@ private struct SwiftMessageModifier: ViewModifier where
func body(content: Content) -> some View {
content
.onChange(of: message) { message in
- if let message {
- let show: @MainActor (SwiftMessages.Config, UIView) -> Void = swiftMessages?.show(config:view:) ?? SwiftMessages.show(config:view:)
+ let show: @MainActor (SwiftMessages.Config, UIView) -> Void = swiftMessages?.show(config:view:) ?? SwiftMessages.show(config:view:)
+ let hideAll: @MainActor () -> Void = swiftMessages?.hideAll ?? SwiftMessages.hideAll
+ switch message {
+ case let message?:
let view = MessageHostingView(id: message.id, content: messageContent(message))
var config = config ?? swiftMessages?.defaultConfig ?? SwiftMessages.defaultConfig
config.eventListeners.append { event in
@@ -84,7 +86,10 @@ private struct SwiftMessageModifier: ViewModifier where
self.message = nil
}
}
+ hideAll()
show(config, view)
+ case .none:
+ hideAll()
}
}
}
From fa5f863eaadaee3629bc4fbf6be6448a1d90c4d8 Mon Sep 17 00:00:00 2001
From: AlbertoSamele <51241132+AlbertoSamele@users.noreply.github.com>
Date: Tue, 23 Jan 2024 18:15:13 +0000
Subject: [PATCH 28/38] Fixes #207 (#484)
---
Demo/Demo.xcodeproj/project.pbxproj | 9 +-
.../xcshareddata/xcschemes/Demo.xcscheme | 7 -
Demo/Demo/Base.lproj/LaunchScreen.storyboard | 13 +-
Demo/Demo/Base.lproj/Main.storyboard | 297 ++++++++++--------
Demo/Demo/ExploreViewController.swift | 15 +-
README.md | 5 +-
SwiftMessages.xcodeproj/project.pbxproj | 4 +
SwiftMessages/AccessibleMessage.swift | 3 +-
SwiftMessages/HapticMessage.swift | 16 +
SwiftMessages/MessageView.swift | 102 +++---
SwiftMessages/Presenter.swift | 6 +
SwiftMessages/SwiftMessages.swift | 32 +-
SwiftMessages/UIWindow+Extensions.swift | 14 +-
SwiftMessages/WindowViewController.swift | 28 +-
.../SwiftUIDemo.xcodeproj/project.pbxproj | 6 +-
15 files changed, 315 insertions(+), 242 deletions(-)
create mode 100644 SwiftMessages/HapticMessage.swift
diff --git a/Demo/Demo.xcodeproj/project.pbxproj b/Demo/Demo.xcodeproj/project.pbxproj
index e7d3b1e..57a9b7a 100644
--- a/Demo/Demo.xcodeproj/project.pbxproj
+++ b/Demo/Demo.xcodeproj/project.pbxproj
@@ -200,7 +200,6 @@
TargetAttributes = {
86AEDCE11D5D1DB70030232E = {
CreatedOnToolsVersion = 7.3.1;
- DevelopmentTeam = 38R82CD868;
LastSwiftMigration = 1020;
};
};
@@ -427,11 +426,11 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
- DEVELOPMENT_TEAM = 38R82CD868;
+ DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Demo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = it.swiftkick.Demo;
+ PRODUCT_BUNDLE_IDENTIFIER = it.swiftkick.SwiftMessages.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -444,11 +443,11 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
- DEVELOPMENT_TEAM = 38R82CD868;
+ DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = Demo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = it.swiftkick.Demo;
+ PRODUCT_BUNDLE_IDENTIFIER = it.swiftkick.SwiftMessages.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme b/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme
index 847d629..db82f1f 100644
--- a/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme
+++ b/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme
@@ -50,13 +50,6 @@
ReferencedContainer = "container:Demo.xcodeproj">
-
-
-
-
-
-
-
-
+
+
-
-
+
@@ -22,14 +19,14 @@
-
+
-
+
diff --git a/Demo/Demo/Base.lproj/Main.storyboard b/Demo/Demo/Base.lproj/Main.storyboard
index 08ab75d..c38d670 100644
--- a/Demo/Demo/Base.lproj/Main.storyboard
+++ b/Demo/Demo/Base.lproj/Main.storyboard
@@ -1,8 +1,10 @@
-
+
-
+
+
+
@@ -30,10 +32,10 @@
-
+
-
+
@@ -47,7 +49,7 @@
-
+
@@ -67,21 +69,21 @@
-
+
-
+
-
+
-
+
-
+
@@ -102,21 +104,21 @@
-
+
-
+
-
+
-
+
-
+
@@ -137,21 +139,21 @@
-
+
-
+
-
+
-
+
-
+
@@ -171,21 +173,21 @@
-
+
-
+
-
+
-
+
-
+
@@ -223,25 +225,25 @@
-
+
-
+
-
+
-
+
-
+
@@ -260,21 +262,21 @@
-
-
+
+
-
+
-
+
-
+
@@ -293,11 +295,11 @@
-
-
+
+
-
+
@@ -306,7 +308,7 @@
-
+
@@ -326,11 +328,11 @@
-
-
+
+
-
+
@@ -339,7 +341,7 @@
-
+
@@ -360,19 +362,19 @@
-
+
-
+
-
+
-
+
@@ -391,20 +393,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
@@ -427,20 +461,20 @@
-
-
+
+
-
+
-
+
-
+
@@ -460,11 +494,11 @@
-
-
+
+
-
+
@@ -473,7 +507,7 @@
-
+
@@ -494,20 +528,20 @@
-
-
+
+
-
+
-
+
-
+
@@ -527,19 +561,19 @@
-
+
-
+
-
+
-
+
@@ -556,20 +590,20 @@
-
-
+
+
-
+
-
+
-
+
@@ -585,20 +619,20 @@
-
-
+
+
-
+
-
+
-
+
@@ -614,48 +648,48 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -663,32 +697,32 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -780,6 +814,7 @@
+
@@ -810,10 +845,10 @@
-
+
-
+
@@ -827,7 +862,7 @@
-
+
@@ -841,7 +876,7 @@
-
+
@@ -855,7 +890,7 @@
-
+
@@ -869,7 +904,7 @@
-
+
@@ -883,7 +918,7 @@
-
+
@@ -897,7 +932,7 @@
-
+
@@ -913,7 +948,7 @@
-
+
@@ -933,7 +968,7 @@
-
+
@@ -951,19 +986,19 @@
-
+
-
+
-
+
-
+
@@ -976,14 +1011,14 @@
-
+
-
+
-
+
@@ -996,14 +1031,14 @@
-
+
-
+
-
+
@@ -1049,13 +1084,13 @@
-
+
-
+
@@ -1072,7 +1107,7 @@
-
+
@@ -1084,11 +1119,17 @@
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/Demo/Demo/ExploreViewController.swift b/Demo/Demo/ExploreViewController.swift
index d39009a..5d34762 100644
--- a/Demo/Demo/ExploreViewController.swift
+++ b/Demo/Demo/ExploreViewController.swift
@@ -41,16 +41,16 @@ class ExploreViewController: UITableViewController, UITextFieldDelegate {
switch theme.selectedSegmentIndex {
case 0:
- view.configureTheme(.info, iconStyle: iconStyle)
+ view.configureTheme(.info, iconStyle: iconStyle, includeHaptic: hapticFeedback.isOn)
view.accessibilityPrefix = "info"
case 1:
- view.configureTheme(.success, iconStyle: iconStyle)
+ view.configureTheme(.success, iconStyle: iconStyle, includeHaptic: hapticFeedback.isOn)
view.accessibilityPrefix = "success"
case 2:
- view.configureTheme(.warning, iconStyle: iconStyle)
+ view.configureTheme(.warning, iconStyle: iconStyle, includeHaptic: hapticFeedback.isOn)
view.accessibilityPrefix = "warning"
case 3:
- view.configureTheme(.error, iconStyle: iconStyle)
+ view.configureTheme(.error, iconStyle: iconStyle, includeHaptic: hapticFeedback.isOn)
view.accessibilityPrefix = "error"
default:
let iconText = ["🐸", "🐷", "🐬", "🐠", "🐍", "🐹", "🐼"].randomElement()
@@ -140,7 +140,11 @@ class ExploreViewController: UITableViewController, UITextFieldDelegate {
break
}
}
-
+
+ if view.defaultHaptic == nil && hapticFeedback.isOn {
+ config.haptic = .success
+ }
+
// Show
SwiftMessages.show(config: config, view: view)
}
@@ -154,6 +158,7 @@ class ExploreViewController: UITableViewController, UITextFieldDelegate {
@IBOutlet weak var duration: UISegmentedControl!
@IBOutlet weak var dimMode: UISegmentedControl!
@IBOutlet weak var interactiveHide: UISwitch!
+ @IBOutlet weak var hapticFeedback: UISwitch!
@IBOutlet weak var layout: UISegmentedControl!
@IBOutlet weak var theme: UISegmentedControl!
@IBOutlet weak var iconStyle: UISegmentedControl!
diff --git a/README.md b/README.md
index 6a6f5af..abec2f0 100644
--- a/README.md
+++ b/README.md
@@ -133,6 +133,9 @@ config.dimMode = .gray(interactive: true)
// Disable the interactive pan-to-hide gesture.
config.interactiveHide = false
+// Specify haptic feedback (see also MessageView/configureTheme)
+config.haptic = .success
+
// Specify a status bar style to if the message is displayed directly under the status bar.
config.preferredStatusBarStyle = .lightContent
@@ -407,7 +410,7 @@ A common mistake is attempting to remove an element by setting the corresponding
`MessageView` provides numerous methods that follow the `configure*` naming convention:
````swift
-view.configureTheme(.warning)
+view.configureTheme(.warning, includeHaptic: true)
view.configureContent(title: "Warning", body: "Consider yourself warned.", iconText: "🤔")
````
diff --git a/SwiftMessages.xcodeproj/project.pbxproj b/SwiftMessages.xcodeproj/project.pbxproj
index 19d5bcd..2ea0092 100644
--- a/SwiftMessages.xcodeproj/project.pbxproj
+++ b/SwiftMessages.xcodeproj/project.pbxproj
@@ -55,6 +55,7 @@
228F7DDE2ACF703A006C9644 /* MessageHostingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DDB2ACF7039006C9644 /* MessageHostingView.swift */; };
228F7DDF2ACF703A006C9644 /* SwiftMessageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DDC2ACF703A006C9644 /* SwiftMessageModifier.swift */; };
228F7DE02ACF703A006C9644 /* MessageViewConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 228F7DDD2ACF703A006C9644 /* MessageViewConvertible.swift */; };
+ 22982C172B6030B000852311 /* HapticMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22982C162B6030B000852311 /* HapticMessage.swift */; };
2298C2051EE47DC900E2DDC1 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2041EE47DC900E2DDC1 /* Weak.swift */; };
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2061EE480D000E2DDC1 /* Animator.swift */; };
2298C2091EE486E300E2DDC1 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */; };
@@ -147,6 +148,7 @@
228F7DDB2ACF7039006C9644 /* MessageHostingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageHostingView.swift; sourceTree = ""; };
228F7DDC2ACF703A006C9644 /* SwiftMessageModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftMessageModifier.swift; sourceTree = ""; };
228F7DDD2ACF703A006C9644 /* MessageViewConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageViewConvertible.swift; sourceTree = ""; };
+ 22982C162B6030B000852311 /* HapticMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticMessage.swift; sourceTree = ""; };
2298C2041EE47DC900E2DDC1 /* Weak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Weak.swift; sourceTree = ""; };
2298C2061EE480D000E2DDC1 /* Animator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animator.swift; sourceTree = ""; };
2298C2081EE486E300E2DDC1 /* TopBottomAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopBottomAnimation.swift; sourceTree = ""; };
@@ -319,6 +321,7 @@
864495551D4F7C390056EB2A /* Identifiable.swift */,
86AAF81D1D5549680031EE32 /* MarginAdjustable.swift */,
22E307FE1E74C5B100E35893 /* AccessibleMessage.swift */,
+ 22982C162B6030B000852311 /* HapticMessage.swift */,
86AAF82A1D580DD70031EE32 /* Error.swift */,
2298C2061EE480D000E2DDC1 /* Animator.swift */,
2298C2041EE47DC900E2DDC1 /* Weak.swift */,
@@ -560,6 +563,7 @@
86BBA9011D5E040600FE8F16 /* PassthroughWindow.swift in Sources */,
2298C2071EE480D000E2DDC1 /* Animator.swift in Sources */,
22D3B4562B1CEF76002D8665 /* Task+Extensions.swift in Sources */,
+ 22982C172B6030B000852311 /* HapticMessage.swift in Sources */,
86BBA9031D5E040600FE8F16 /* UIViewController+Extensions.swift in Sources */,
228F7DDF2ACF703A006C9644 /* SwiftMessageModifier.swift in Sources */,
224FB69921153B440081D4DE /* CALayer+Extensions.swift in Sources */,
diff --git a/SwiftMessages/AccessibleMessage.swift b/SwiftMessages/AccessibleMessage.swift
index d540ece..71590aa 100644
--- a/SwiftMessages/AccessibleMessage.swift
+++ b/SwiftMessages/AccessibleMessage.swift
@@ -9,8 +9,7 @@
import Foundation
/**
- Message views that `AccessibleMessage`, as `MessageView` does will
- have proper accessibility behavior when displaying messages.
+ Message views that conform to `AccessibleMessage` will have proper accessibility behavior when displaying messages.
`MessageView` implements this protocol.
*/
public protocol AccessibleMessage {
diff --git a/SwiftMessages/HapticMessage.swift b/SwiftMessages/HapticMessage.swift
new file mode 100644
index 0000000..fa86614
--- /dev/null
+++ b/SwiftMessages/HapticMessage.swift
@@ -0,0 +1,16 @@
+//
+// HapticMessage.swift
+// SwiftMessages
+//
+// Created by Timothy Moose on 1/23/24.
+// Copyright © 2024 SwiftKick Mobile. All rights reserved.
+//
+
+import Foundation
+
+/**
+ Message views that conform to `HapticMessage` can specify a haptic feedback to be used when presented.
+ */
+protocol HapticMessage {
+ var defaultHaptic: SwiftMessages.Haptic? { get }
+}
diff --git a/SwiftMessages/MessageView.swift b/SwiftMessages/MessageView.swift
index c71141a..6384917 100644
--- a/SwiftMessages/MessageView.swift
+++ b/SwiftMessages/MessageView.swift
@@ -10,8 +10,15 @@ import UIKit
/*
*/
-open class MessageView: BaseView, Identifiable, AccessibleMessage {
+open class MessageView: BaseView, Identifiable, AccessibleMessage, HapticMessage {
+
+ /*
+ MARK: - Haptic feedback
+ */
+ /// The default haptic feedback to be used when the message is presented.
+ open var defaultHaptic: SwiftMessages.Haptic?
+
/*
MARK: - Button tap handler
*/
@@ -248,73 +255,74 @@ extension MessageView {
- Parameter theme: The theme type to use.
- Parameter iconStyle: The icon style to use. Defaults to `.Default`.
+ - Parameter useHaptics: If `true`, configures an appropriate haptic based on theme. Defaults to `false`.
*/
- public func configureTheme(_ theme: Theme, iconStyle: IconStyle = .default) {
+ public func configureTheme(_ theme: Theme, iconStyle: IconStyle = .default, includeHaptic: Bool = false) {
let iconImage = iconStyle.image(theme: theme)
let backgroundColor: UIColor
let foregroundColor: UIColor
let defaultBackgroundColor: UIColor
- let defaultForegroundColor: UIColor
switch theme {
case .info:
defaultBackgroundColor = UIColor(red: 225.0/255.0, green: 225.0/255.0, blue: 225.0/255.0, alpha: 1.0)
- defaultForegroundColor = UIColor.darkText
case .success:
defaultBackgroundColor = UIColor(red: 97.0/255.0, green: 161.0/255.0, blue: 23.0/255.0, alpha: 1.0)
- defaultForegroundColor = UIColor.white
case .warning:
defaultBackgroundColor = UIColor(red: 246.0/255.0, green: 197.0/255.0, blue: 44.0/255.0, alpha: 1.0)
- defaultForegroundColor = UIColor.white
case .error:
defaultBackgroundColor = UIColor(red: 249.0/255.0, green: 66.0/255.0, blue: 47.0/255.0, alpha: 1.0)
- defaultForegroundColor = UIColor.white
}
- if #available(iOS 13.0, *) {
+ if includeHaptic {
switch theme {
- case .info:
- backgroundColor = UIColor {
- switch $0.userInterfaceStyle {
- case .dark, .unspecified: return UIColor(red: 125/255.0, green: 125/255.0, blue: 125/255.0, alpha: 1.0)
- case .light: fallthrough
- @unknown default:
- return defaultBackgroundColor
- }
+ case .success, .info:
+ defaultHaptic = SwiftMessages.Haptic.success
+ case .warning:
+ defaultHaptic = SwiftMessages.Haptic.warning
+ case .error:
+ defaultHaptic = SwiftMessages.Haptic.error
+ }
+ }
+ switch theme {
+ case .info:
+ backgroundColor = UIColor {
+ switch $0.userInterfaceStyle {
+ case .dark, .unspecified: return UIColor(red: 125/255.0, green: 125/255.0, blue: 125/255.0, alpha: 1.0)
+ case .light: fallthrough
+ @unknown default:
+ return defaultBackgroundColor
}
- foregroundColor = .label
- case .success:
- backgroundColor = UIColor {
- switch $0.userInterfaceStyle {
- case .dark, .unspecified: return UIColor(red: 55/255.0, green: 122/255.0, blue: 0/255.0, alpha: 1.0)
- case .light: fallthrough
- @unknown default:
- return defaultBackgroundColor
- }
+ }
+ foregroundColor = .label
+ case .success:
+ backgroundColor = UIColor {
+ switch $0.userInterfaceStyle {
+ case .dark, .unspecified: return UIColor(red: 55/255.0, green: 122/255.0, blue: 0/255.0, alpha: 1.0)
+ case .light: fallthrough
+ @unknown default:
+ return defaultBackgroundColor
}
- foregroundColor = .white
- case .warning:
- backgroundColor = UIColor {
- switch $0.userInterfaceStyle {
- case .dark, .unspecified: return UIColor(red: 239/255.0, green: 184/255.0, blue: 10/255.0, alpha: 1.0)
- case .light: fallthrough
- @unknown default:
- return defaultBackgroundColor
- }
+ }
+ foregroundColor = .white
+ case .warning:
+ backgroundColor = UIColor {
+ switch $0.userInterfaceStyle {
+ case .dark, .unspecified: return UIColor(red: 239/255.0, green: 184/255.0, blue: 10/255.0, alpha: 1.0)
+ case .light: fallthrough
+ @unknown default:
+ return defaultBackgroundColor
}
- foregroundColor = .white
- case .error:
- backgroundColor = UIColor {
- switch $0.userInterfaceStyle {
- case .dark, .unspecified: return UIColor(red: 195/255.0, green: 12/255.0, blue: 12/255.0, alpha: 1.0)
- case .light: fallthrough
- @unknown default:
- return defaultBackgroundColor
- }
+ }
+ foregroundColor = .white
+ case .error:
+ backgroundColor = UIColor {
+ switch $0.userInterfaceStyle {
+ case .dark, .unspecified: return UIColor(red: 195/255.0, green: 12/255.0, blue: 12/255.0, alpha: 1.0)
+ case .light: fallthrough
+ @unknown default:
+ return defaultBackgroundColor
}
- foregroundColor = .white
}
- } else {
- backgroundColor = defaultBackgroundColor
- foregroundColor = defaultForegroundColor
+ foregroundColor = .white
}
configureTheme(backgroundColor: backgroundColor, foregroundColor: foregroundColor, iconImage: iconImage)
}
diff --git a/SwiftMessages/Presenter.swift b/SwiftMessages/Presenter.swift
index 7719a57..e7f5049 100644
--- a/SwiftMessages/Presenter.swift
+++ b/SwiftMessages/Presenter.swift
@@ -129,6 +129,12 @@ class Presenter: NSObject {
try presentationContext = getPresentationContext()
install()
self.config.eventListeners.forEach { $0(.willShow(self.view)) }
+ switch (self.view as? HapticMessage)?.defaultHaptic ?? config.haptic {
+ case .error?: UINotificationFeedbackGenerator().notificationOccurred(.error)
+ case .warning?: UINotificationFeedbackGenerator().notificationOccurred(.warning)
+ case .success?: UINotificationFeedbackGenerator().notificationOccurred(.success)
+ default: break
+ }
showAnimation() { completed in
completion(completed)
if completed {
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index 1245f06..b41a4d0 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -153,6 +153,20 @@ open class SwiftMessages {
case indefinite(delay: TimeInterval, minimum: TimeInterval)
}
+ /**
+ Specifies notification's haptic feedback to be used on `MessageView` display
+ */
+
+ /**
+ Specifies an optional haptic feedback to be used on `MessageView` display
+ */
+ public enum Haptic {
+ case success
+ case warning
+ case error
+ }
+
+
/**
Specifies options for dimming the background behind the message view
similar to a popover view controller.
@@ -263,16 +277,7 @@ open class SwiftMessages {
Specifies how the container for presenting the message view
is selected. The default is `.Automatic`.
*/
- public var presentationContext = PresentationContext.automatic {
- didSet {
- if case .windowScene = presentationContext {
- guard #available(iOS 13.0, *) else {
- assertionFailure("windowScene is not supported below iOS 13.0.")
- return
- }
- }
- }
- }
+ public var presentationContext = PresentationContext.automatic
/**
Specifies the duration of the message view's time on screen before it is
@@ -286,6 +291,13 @@ open class SwiftMessages {
*/
public var dimMode = DimMode.none
+
+ /**
+ Specifies notification's haptic feedback to be played on `MessageView` display.
+ No default value is provided.
+ */
+ public var haptic: Haptic? = nil
+
/**
Specifies whether or not the interactive pan-to-hide gesture is enabled
on the message view. For views that implement the `BackgroundViewable`
diff --git a/SwiftMessages/UIWindow+Extensions.swift b/SwiftMessages/UIWindow+Extensions.swift
index 316fcac..6a626f4 100644
--- a/SwiftMessages/UIWindow+Extensions.swift
+++ b/SwiftMessages/UIWindow+Extensions.swift
@@ -11,15 +11,11 @@ import UIKit
extension UIWindow {
#if !SWIFTMESSAGES_APP_EXTENSIONS
static var keyWindow: UIWindow? {
- if #available(iOS 13.0, *) {
- return UIApplication.shared.connectedScenes
- .sorted { $0.activationState.sortPriority < $1.activationState.sortPriority }
- .compactMap { $0 as? UIWindowScene }
- .compactMap { $0.windows.first { $0.isKeyWindow } }
- .first
- } else {
- return UIApplication.shared.keyWindow
- }
+ return UIApplication.shared.connectedScenes
+ .sorted { $0.activationState.sortPriority < $1.activationState.sortPriority }
+ .compactMap { $0 as? UIWindowScene }
+ .compactMap { $0.windows.first { $0.isKeyWindow } }
+ .first
}
#endif
}
diff --git a/SwiftMessages/WindowViewController.swift b/SwiftMessages/WindowViewController.swift
index 9c2b721..30d77f9 100644
--- a/SwiftMessages/WindowViewController.swift
+++ b/SwiftMessages/WindowViewController.swift
@@ -27,24 +27,18 @@ open class WindowViewController: UIViewController
self.view = view
window.rootViewController = self
window.windowLevel = config.windowLevel ?? UIWindow.Level.normal
- if #available(iOS 13, *) {
- window.overrideUserInterfaceStyle = config.overrideUserInterfaceStyle
- }
+ window.overrideUserInterfaceStyle = config.overrideUserInterfaceStyle
}
func install() {
- if #available(iOS 13, *) {
- window?.windowScene = config.windowScene
- #if !SWIFTMESSAGES_APP_EXTENSIONS
- previousKeyWindow = UIWindow.keyWindow
- #endif
- show(
- becomeKey: config.shouldBecomeKeyWindow,
- frame: config.windowScene?.coordinateSpace.bounds
- )
- } else {
- show(becomeKey: config.shouldBecomeKeyWindow)
- }
+ window?.windowScene = config.windowScene
+ #if !SWIFTMESSAGES_APP_EXTENSIONS
+ previousKeyWindow = UIWindow.keyWindow
+ #endif
+ show(
+ becomeKey: config.shouldBecomeKeyWindow,
+ frame: config.windowScene?.coordinateSpace.bounds
+ )
}
private func show(becomeKey: Bool, frame: CGRect? = nil) {
@@ -61,9 +55,7 @@ open class WindowViewController: UIViewController
if window?.isKeyWindow == true {
previousKeyWindow?.makeKey()
}
- if #available(iOS 13, *) {
- window?.windowScene = nil
- }
+ window?.windowScene = nil
window?.isHidden = true
window = nil
}
diff --git a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
index 790676b..f1519c4 100644
--- a/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
+++ b/SwiftUIDemo/SwiftUIDemo.xcodeproj/project.pbxproj
@@ -367,6 +367,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"SwiftUIDemo/Preview Content\"";
+ DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SwiftUIDemo/Info.plist;
@@ -380,7 +381,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.swiftkickmobile.SwiftUIDemo;
+ PRODUCT_BUNDLE_IDENTIFIER = com.swiftkickmobile.SwiftMessages.SwiftUIDemo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
@@ -396,6 +397,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"SwiftUIDemo/Preview Content\"";
+ DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SwiftUIDemo/Info.plist;
@@ -409,7 +411,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.swiftkickmobile.SwiftUIDemo;
+ PRODUCT_BUNDLE_IDENTIFIER = com.swiftkickmobile.SwiftMessages.SwiftUIDemo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
From b899be48a61ddb209695a8d5e411189b704a7fa3 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Tue, 6 Feb 2024 17:19:57 -0600
Subject: [PATCH 29/38] Update changelog
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c068572..8316ae2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
### Features
* Add a variation on the `.swiftMessage()` modifier that takes a view builder instead of requiring that the bound value conform to `MessageViewConvertible`. This syntax is more similar to the familiar `sheet()` modifier syntax and provides more flexibility for constructing message views.
+* #207 Add optional haptic feedback
### Changes
From a49306be3a040d14a6196ba435e5cf9c43309cd6 Mon Sep 17 00:00:00 2001
From: Kaleb Cooper <94631017+kalebzen@users.noreply.github.com>
Date: Sun, 23 Jun 2024 13:28:37 -0500
Subject: [PATCH 30/38] remove MainActor from class declaration (#543)
---
SwiftMessages/SwiftMessages.swift | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index b41a4d0..5d96b3b 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -16,7 +16,6 @@ private let globalInstance = SwiftMessages()
It behaves like a queue, only showing one message at a time. Message views that
adopt the `Identifiable` protocol (as `MessageView` does) will have duplicates removed.
*/
-@MainActor
open class SwiftMessages {
/**
@@ -408,6 +407,7 @@ open class SwiftMessages {
- Parameter config: The configuration options.
- Parameter view: The view to be displayed.
*/
+ @MainActor
open func show(config: Config, view: UIView) {
let presenter = Presenter(config: config, view: view, delegate: self)
enqueue(presenter: presenter)
@@ -420,6 +420,7 @@ open class SwiftMessages {
- Parameter config: The configuration options.
- Parameter view: The view to be displayed.
*/
+ @MainActor
public func show(view: UIView) {
show(config: defaultConfig, view: view)
}
@@ -462,6 +463,7 @@ open class SwiftMessages {
/**
Hide the current message being displayed by animating it away.
*/
+ @MainActor
open func hide(animated: Bool = true) {
hideCurrent(animated: animated)
}
@@ -470,6 +472,7 @@ open class SwiftMessages {
Hide the current message, if there is one, by animating it away and
clear the message queue.
*/
+ @MainActor
open func hideAll() {
queue.removeAll()
delays.removeAll()
@@ -483,6 +486,7 @@ open class SwiftMessages {
views, such as `MessageView`, that adopt the `Identifiable` protocol.
- Parameter id: The identifier of the message to remove.
*/
+ @MainActor
open func hide(id: String) {
if id == _current?.id {
hideCurrent()
@@ -497,6 +501,7 @@ open class SwiftMessages {
given message ID are equal. This can be useful for messages that may be
shown from multiple code paths to ensure that all paths are ready to hide.
*/
+ @MainActor
open func hideCounted(id: String) {
if let count = counts[id] {
if count < 2 {
@@ -567,17 +572,19 @@ open class SwiftMessages {
private var presenters = Set()
}
+ @MainActor
func show(presenter: Presenter) {
enqueue(presenter: presenter)
}
fileprivate var queue: [Presenter] = []
+ @MainActor
fileprivate var delays = Delays()
fileprivate var counts: [String : Int] = [:]
fileprivate var _current: Presenter? = nil {
didSet {
if oldValue != nil {
- Task { [weak self] in
+ Task { @MainActor [weak self] in
try? await Task.sleep(seconds: self?.pauseBetweenMessages ?? 0)
self?.dequeueNext()
}
@@ -585,6 +592,7 @@ open class SwiftMessages {
}
}
+ @MainActor
fileprivate func enqueue(presenter: Presenter) {
if presenter.config.ignoreDuplicates {
counts[presenter.id] = (counts[presenter.id] ?? 0) + 1
@@ -611,6 +619,7 @@ open class SwiftMessages {
}
}
+ @MainActor
fileprivate func dequeueNext() {
guard queue.count > 0 else { return }
if let _current, !_current.isOrphaned { return }
@@ -637,6 +646,7 @@ open class SwiftMessages {
}
}
+ @MainActor
fileprivate func internalHide(presenter: Presenter) {
if presenter == _current {
hideCurrent()
@@ -646,6 +656,7 @@ open class SwiftMessages {
}
}
+ @MainActor
fileprivate func hideCurrent(animated: Bool = true) {
guard let current = _current, !current.isHiding else { return }
let action = { [weak self] in
@@ -665,6 +676,7 @@ open class SwiftMessages {
fileprivate weak var autohideToken: Presenter?
+ @MainActor
fileprivate func queueAutoHide() {
guard let current = _current else { return }
autohideToken = current
@@ -707,6 +719,7 @@ extension SwiftMessages {
- Parameter id: The id of a message that adopts `Identifiable`.
- Returns: The view with matching id if currently being shown or hidden.
*/
+ @MainActor
public func current(id: String) -> T? {
_current?.id == id ? _current?.view as? T : nil
}
@@ -717,6 +730,7 @@ extension SwiftMessages {
- Parameter id: The id of a message that adopts `Identifiable`.
- Returns: The view with matching id if currently queued to be shown.
*/
+ @MainActor
public func queued(id: String) -> T? {
queue.first { $0.id == id }?.view as? T
}
@@ -728,6 +742,7 @@ extension SwiftMessages {
- Parameter id: The id of a message that adopts `Identifiable`.
- Returns: The view with matching id if currently queued to be shown.
*/
+ @MainActor
public func currentOrQueued(id: String) -> T? {
return current(id: id) ?? queued(id: id)
}
@@ -739,10 +754,12 @@ extension SwiftMessages {
extension SwiftMessages: PresenterDelegate {
+ @MainActor
func hide(presenter: Presenter) {
self.internalHide(presenter: presenter)
}
+ @MainActor
public func hide(animator: Animator) {
guard let presenter = self.presenter(forAnimator: animator) else { return }
self.internalHide(presenter: presenter)
@@ -752,6 +769,7 @@ extension SwiftMessages: PresenterDelegate {
autohideToken = nil
}
+ @MainActor
public func panEnded(animator: Animator) {
queueAutoHide()
}
@@ -879,26 +897,32 @@ extension SwiftMessages {
globalInstance.show(config: config, viewProvider: viewProvider)
}
+ @MainActor
public static func show(view: UIView) {
globalInstance.show(view: view)
}
+ @MainActor
public static func show(config: Config, view: UIView) {
globalInstance.show(config: config, view: view)
}
+ @MainActor
public static func hide(animated: Bool = true) {
globalInstance.hide(animated: animated)
}
+ @MainActor
public static func hideAll() {
globalInstance.hideAll()
}
+ @MainActor
public static func hide(id: String) {
globalInstance.hide(id: id)
}
+ @MainActor
public static func hideCounted(id: String) {
globalInstance.hideCounted(id: id)
}
@@ -921,14 +945,17 @@ extension SwiftMessages {
}
}
+ @MainActor
public static func current(id: String) -> T? {
return globalInstance.current(id: id)
}
+ @MainActor
public static func queued(id: String) -> T? {
return globalInstance.queued(id: id)
}
+ @MainActor
public static func currentOrQueued(id: String) -> T? {
return globalInstance.currentOrQueued(id: id)
}
From 66841d32bd727ce09d13a3b09ca27e3209f8001f Mon Sep 17 00:00:00 2001
From: Julien Di Marco
Date: Sun, 23 Jun 2024 22:39:16 +0200
Subject: [PATCH 31/38] feat(TopBottomPresentable): Adds 'TopBottomPresentable'
protocol, allow any Animator to be presented correctly by the `Presenter`
(#548)
---
CHANGELOG.md | 6 +++
SwiftMessages.podspec | 2 +-
SwiftMessages.xcodeproj/project.pbxproj | 26 ++++++----
SwiftMessages/Animator.swift | 1 +
SwiftMessages/Presenter.swift | 1 +
.../SwiftMessages.Config+Extensions.swift | 2 +-
SwiftMessages/SwiftMessages.swift | 7 +--
SwiftMessages/TopBottomAnimation.swift | 12 ++---
SwiftMessages/TopBottomAnimationStyle.swift | 12 +++++
SwiftMessages/TopBottomPresentable.swift | 49 +++++++++++++++++++
.../UIViewController+Extensions.swift | 14 ------
11 files changed, 96 insertions(+), 36 deletions(-)
create mode 100644 SwiftMessages/TopBottomAnimationStyle.swift
create mode 100644 SwiftMessages/TopBottomPresentable.swift
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8316ae2..880e47b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
# Change Log
All notable changes to this project will be documented in this file.
+## 10.0.1
+
+## Features
+
+* Adds 'TopBottomPresentable' protocol to allow animators implementation to reuse 'top/bottom' integration in presentation
+
## 10.0.0
### Features
diff --git a/SwiftMessages.podspec b/SwiftMessages.podspec
index 6d1a842..0500d4a 100644
--- a/SwiftMessages.podspec
+++ b/SwiftMessages.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'SwiftMessages'
- spec.version = '10.0.0'
+ spec.version = '10.0.1'
spec.license = { :type => 'MIT' }
spec.homepage = 'https://github.com/SwiftKickMobile/SwiftMessages'
spec.authors = { 'Timothy Moose' => 'tim@swiftkickmobile.com' }
diff --git a/SwiftMessages.xcodeproj/project.pbxproj b/SwiftMessages.xcodeproj/project.pbxproj
index 2ea0092..066f5c7 100644
--- a/SwiftMessages.xcodeproj/project.pbxproj
+++ b/SwiftMessages.xcodeproj/project.pbxproj
@@ -10,6 +10,8 @@
0797E40E26EE12B400691606 /* WindowScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0797E40D26EE12B400691606 /* WindowScene.swift */; };
220655121FAF82B600F4E00F /* MarginAdjustable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */; };
220D386E2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 220D386D2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift */; };
+ 224C3C902C28A2F900B50B18 /* TopBottomPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 224C3C8F2C28A2F900B50B18 /* TopBottomPresentable.swift */; };
+ 224C3C932C28BC4900B50B18 /* TopBottomAnimationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 224C3C922C28BC4400B50B18 /* TopBottomAnimationStyle.swift */; };
224FB69921153B440081D4DE /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 224FB69821153B440081D4DE /* CALayer+Extensions.swift */; };
225304622290C76E00A03ACF /* NSLayoutConstraint+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225304612290C76E00A03ACF /* NSLayoutConstraint+Extensions.swift */; };
225304662293000C00A03ACF /* KeyboardTrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225304652293000C00A03ACF /* KeyboardTrackingView.swift */; };
@@ -103,6 +105,8 @@
0797E40D26EE12B400691606 /* WindowScene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowScene.swift; sourceTree = ""; };
220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MarginAdjustable+Extensions.swift"; sourceTree = ""; };
220D386D2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftMessages.Config+Extensions.swift"; sourceTree = ""; };
+ 224C3C8F2C28A2F900B50B18 /* TopBottomPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBottomPresentable.swift; sourceTree = ""; };
+ 224C3C922C28BC4400B50B18 /* TopBottomAnimationStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBottomAnimationStyle.swift; sourceTree = ""; };
224FB69821153B440081D4DE /* CALayer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Extensions.swift"; sourceTree = ""; };
225304612290C76E00A03ACF /* NSLayoutConstraint+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSLayoutConstraint+Extensions.swift"; sourceTree = ""; };
225304652293000C00A03ACF /* KeyboardTrackingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardTrackingView.swift; sourceTree = ""; };
@@ -314,20 +318,22 @@
864495571D4F7C490056EB2A /* Base */ = {
isa = PBXGroup;
children = (
- 86589D461D64B6E40041676C /* BaseView.swift */,
- 86AAF82C1D580F410031EE32 /* Theme.swift */,
- 8644955C1D4FAF7C0056EB2A /* WindowViewController.swift */,
- 867BED201D622793005212E3 /* BackgroundViewable.swift */,
- 864495551D4F7C390056EB2A /* Identifiable.swift */,
- 86AAF81D1D5549680031EE32 /* MarginAdjustable.swift */,
22E307FE1E74C5B100E35893 /* AccessibleMessage.swift */,
- 22982C162B6030B000852311 /* HapticMessage.swift */,
- 86AAF82A1D580DD70031EE32 /* Error.swift */,
2298C2061EE480D000E2DDC1 /* Animator.swift */,
- 2298C2041EE47DC900E2DDC1 /* Weak.swift */,
+ 867BED201D622793005212E3 /* BackgroundViewable.swift */,
+ 86589D461D64B6E40041676C /* BaseView.swift */,
22F27950210CE25900273E7F /* CornerRoundingView.swift */,
+ 86AAF82A1D580DD70031EE32 /* Error.swift */,
+ 22982C162B6030B000852311 /* HapticMessage.swift */,
+ 864495551D4F7C390056EB2A /* Identifiable.swift */,
225304652293000C00A03ACF /* KeyboardTrackingView.swift */,
+ 86AAF81D1D5549680031EE32 /* MarginAdjustable.swift */,
+ 86AAF82C1D580F410031EE32 /* Theme.swift */,
+ 224C3C922C28BC4400B50B18 /* TopBottomAnimationStyle.swift */,
+ 224C3C8F2C28A2F900B50B18 /* TopBottomPresentable.swift */,
+ 2298C2041EE47DC900E2DDC1 /* Weak.swift */,
0797E40D26EE12B400691606 /* WindowScene.swift */,
+ 8644955C1D4FAF7C0056EB2A /* WindowViewController.swift */,
);
name = Base;
sourceTree = "";
@@ -568,6 +574,7 @@
228F7DDF2ACF703A006C9644 /* SwiftMessageModifier.swift in Sources */,
224FB69921153B440081D4DE /* CALayer+Extensions.swift in Sources */,
22E01F641E74EC8B00ACE19A /* MaskingView.swift in Sources */,
+ 224C3C932C28BC4900B50B18 /* TopBottomAnimationStyle.swift in Sources */,
2298C2051EE47DC900E2DDC1 /* Weak.swift in Sources */,
228F7DE02ACF703A006C9644 /* MessageViewConvertible.swift in Sources */,
86BBA9001D5E040600FE8F16 /* PassthroughView.swift in Sources */,
@@ -578,6 +585,7 @@
22E307FF1E74C5B100E35893 /* AccessibleMessage.swift in Sources */,
220D386E2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift in Sources */,
2270044B1FAFA6DD0045DDC3 /* PhysicsAnimation.swift in Sources */,
+ 224C3C902C28A2F900B50B18 /* TopBottomPresentable.swift in Sources */,
86BBA9041D5E040600FE8F16 /* NSBundle+Extensions.swift in Sources */,
86BBA8FD1D5E03F800FE8F16 /* SwiftMessages.swift in Sources */,
86BBA9021D5E040600FE8F16 /* WindowViewController.swift in Sources */,
diff --git a/SwiftMessages/Animator.swift b/SwiftMessages/Animator.swift
index 346ce2f..c79d0f0 100644
--- a/SwiftMessages/Animator.swift
+++ b/SwiftMessages/Animator.swift
@@ -10,6 +10,7 @@ import UIKit
public typealias AnimationCompletion = (_ completed: Bool) -> Void
+@MainActor
public protocol AnimationDelegate: AnyObject {
func hide(animator: Animator)
func panStarted(animator: Animator)
diff --git a/SwiftMessages/Presenter.swift b/SwiftMessages/Presenter.swift
index e7f5049..667d1eb 100644
--- a/SwiftMessages/Presenter.swift
+++ b/SwiftMessages/Presenter.swift
@@ -8,6 +8,7 @@
import UIKit
+@MainActor
protocol PresenterDelegate: AnimationDelegate {
func hide(presenter: Presenter)
}
diff --git a/SwiftMessages/SwiftMessages.Config+Extensions.swift b/SwiftMessages/SwiftMessages.Config+Extensions.swift
index ac0475d..a17a9f2 100644
--- a/SwiftMessages/SwiftMessages.Config+Extensions.swift
+++ b/SwiftMessages/SwiftMessages.Config+Extensions.swift
@@ -17,7 +17,7 @@ extension SwiftMessages.Config {
}
}
- @available (iOS 13.0, *)
+ @available(iOS 13.0, *)
var windowScene: UIWindowScene? {
switch presentationContext {
case .windowScene(let scene, _): return scene as? UIWindowScene
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index 5d96b3b..315ff3c 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -8,7 +8,6 @@
import UIKit
-@MainActor
private let globalInstance = SwiftMessages()
/**
@@ -774,6 +773,7 @@ extension SwiftMessages: PresenterDelegate {
queueAutoHide()
}
+ @MainActor
private func presenter(forAnimator animator: Animator) -> Presenter? {
if let current = _current, animator === current.animator {
return current
@@ -885,11 +885,12 @@ extension SwiftMessages {
a set of static APIs that wrap calls to this instance. For example, `SwiftMessages.show()`
is equivalent to `SwiftMessages.sharedInstance.show()`.
*/
+ @MainActor
public static var sharedInstance: SwiftMessages {
return globalInstance
}
-
- public static func show(viewProvider: @escaping ViewProvider) {
+
+ nonisolated public static func show(viewProvider: @escaping ViewProvider) {
globalInstance.show(viewProvider: viewProvider)
}
diff --git a/SwiftMessages/TopBottomAnimation.swift b/SwiftMessages/TopBottomAnimation.swift
index a0d440c..49a45ad 100644
--- a/SwiftMessages/TopBottomAnimation.swift
+++ b/SwiftMessages/TopBottomAnimation.swift
@@ -8,16 +8,12 @@
import UIKit
+@MainActor
public class TopBottomAnimation: NSObject, Animator {
- public enum Style {
- case top
- case bottom
- }
-
public weak var delegate: AnimationDelegate?
- public let style: Style
+ public let style: TopBottomAnimationStyle
public var showDuration: TimeInterval = 0.4
@@ -41,11 +37,11 @@ public class TopBottomAnimation: NSObject, Animator {
weak var containerView: UIView?
var context: AnimationContext?
- public init(style: Style) {
+ public init(style: TopBottomAnimationStyle) {
self.style = style
}
- init(style: Style, delegate: AnimationDelegate) {
+ init(style: TopBottomAnimationStyle, delegate: AnimationDelegate) {
self.style = style
self.delegate = delegate
}
diff --git a/SwiftMessages/TopBottomAnimationStyle.swift b/SwiftMessages/TopBottomAnimationStyle.swift
new file mode 100644
index 0000000..626ad09
--- /dev/null
+++ b/SwiftMessages/TopBottomAnimationStyle.swift
@@ -0,0 +1,12 @@
+//
+// TopBottomAnimationStyle.swift
+// SwiftMessages
+//
+// Created by Timothy Moose on 6/23/24.
+// Copyright © 2024 SwiftKick Mobile. All rights reserved.
+//
+
+public enum TopBottomAnimationStyle {
+ case top
+ case bottom
+}
diff --git a/SwiftMessages/TopBottomPresentable.swift b/SwiftMessages/TopBottomPresentable.swift
new file mode 100644
index 0000000..1880416
--- /dev/null
+++ b/SwiftMessages/TopBottomPresentable.swift
@@ -0,0 +1,49 @@
+//
+// File.swift
+//
+//
+// Created by Julien Di Marco on 23/04/2024.
+//
+
+import Foundation
+
+// MARK: - TopBottom Presentable Definition
+
+@MainActor
+protocol TopBottomPresentable {
+ var topBottomStyle: TopBottomAnimationStyle? { get }
+}
+
+// MARK: - TopBottom Presentable Conformances
+
+extension TopBottomAnimation: TopBottomPresentable {
+ var topBottomStyle: TopBottomAnimationStyle? { return style }
+}
+
+extension PhysicsAnimation: TopBottomPresentable {
+ var topBottomStyle: TopBottomAnimationStyle? {
+ switch placement {
+ case .top: return .top
+ case .bottom: return .bottom
+ default: return nil
+ }
+ }
+}
+
+// MARK: - Presentation Style Convenience
+
+extension SwiftMessages.PresentationStyle {
+ /// A temporary workaround to allow custom presentation contexts using `TopBottomAnimation`
+ /// to display properly behind bars. THe long term solution is to refactor all of the
+ /// presentation context logic to work with safe area insets.
+ @MainActor
+ var topBottomStyle: TopBottomAnimationStyle? {
+ switch self {
+ case .top: return .top
+ case .bottom: return .bottom
+ case .custom(let animator as TopBottomPresentable): return animator.topBottomStyle
+ case .center: return nil
+ default: return nil
+ }
+ }
+}
diff --git a/SwiftMessages/UIViewController+Extensions.swift b/SwiftMessages/UIViewController+Extensions.swift
index 7fbd4dd..1400e03 100644
--- a/SwiftMessages/UIViewController+Extensions.swift
+++ b/SwiftMessages/UIViewController+Extensions.swift
@@ -85,17 +85,3 @@ extension UIViewController {
return true
}
}
-
-extension SwiftMessages.PresentationStyle {
- /// A temporary workaround to allow custom presentation contexts using `TopBottomAnimation`
- /// to display properly behind bars. THe long term solution is to refactor all of the
- /// presentation context logic to work with safe area insets.
- var topBottomStyle: TopBottomAnimation.Style? {
- switch self {
- case .top: return .top
- case .bottom: return .bottom
- case .custom(let animator): return (animator as? TopBottomAnimation)?.style
- case .center: return nil
- }
- }
-}
From 8b9bc1ce25d11a83e7999aa74c4ebcda47596e63 Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Fri, 2 Aug 2024 15:07:52 -0500
Subject: [PATCH 32/38] Make SwiftMessages initializer nonisolated
---
SwiftMessages/SwiftMessages.swift | 44 +++++--------------------------
1 file changed, 7 insertions(+), 37 deletions(-)
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index 315ff3c..0280bbe 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -15,6 +15,7 @@ private let globalInstance = SwiftMessages()
It behaves like a queue, only showing one message at a time. Message views that
adopt the `Identifiable` protocol (as `MessageView` does) will have duplicates removed.
*/
+@MainActor
open class SwiftMessages {
/**
@@ -164,7 +165,6 @@ open class SwiftMessages {
case error
}
-
/**
Specifies options for dimming the background behind the message view
similar to a popover view controller.
@@ -398,15 +398,14 @@ open class SwiftMessages {
/**
Not much to say here.
*/
- public init() {}
-
+ nonisolated public init() {}
+
/**
Adds the given configuration and view to the message queue to be displayed.
- Parameter config: The configuration options.
- Parameter view: The view to be displayed.
*/
- @MainActor
open func show(config: Config, view: UIView) {
let presenter = Presenter(config: config, view: view, delegate: self)
enqueue(presenter: presenter)
@@ -419,7 +418,6 @@ open class SwiftMessages {
- Parameter config: The configuration options.
- Parameter view: The view to be displayed.
*/
- @MainActor
public func show(view: UIView) {
show(config: defaultConfig, view: view)
}
@@ -462,7 +460,6 @@ open class SwiftMessages {
/**
Hide the current message being displayed by animating it away.
*/
- @MainActor
open func hide(animated: Bool = true) {
hideCurrent(animated: animated)
}
@@ -471,7 +468,6 @@ open class SwiftMessages {
Hide the current message, if there is one, by animating it away and
clear the message queue.
*/
- @MainActor
open func hideAll() {
queue.removeAll()
delays.removeAll()
@@ -485,7 +481,6 @@ open class SwiftMessages {
views, such as `MessageView`, that adopt the `Identifiable` protocol.
- Parameter id: The identifier of the message to remove.
*/
- @MainActor
open func hide(id: String) {
if id == _current?.id {
hideCurrent()
@@ -500,7 +495,6 @@ open class SwiftMessages {
given message ID are equal. This can be useful for messages that may be
shown from multiple code paths to ensure that all paths are ready to hide.
*/
- @MainActor
open func hideCounted(id: String) {
if let count = counts[id] {
if count < 2 {
@@ -571,19 +565,17 @@ open class SwiftMessages {
private var presenters = Set()
}
- @MainActor
func show(presenter: Presenter) {
enqueue(presenter: presenter)
}
fileprivate var queue: [Presenter] = []
- @MainActor
fileprivate var delays = Delays()
fileprivate var counts: [String : Int] = [:]
fileprivate var _current: Presenter? = nil {
didSet {
if oldValue != nil {
- Task { @MainActor [weak self] in
+ Task { [weak self] in
try? await Task.sleep(seconds: self?.pauseBetweenMessages ?? 0)
self?.dequeueNext()
}
@@ -591,7 +583,6 @@ open class SwiftMessages {
}
}
- @MainActor
fileprivate func enqueue(presenter: Presenter) {
if presenter.config.ignoreDuplicates {
counts[presenter.id] = (counts[presenter.id] ?? 0) + 1
@@ -618,7 +609,6 @@ open class SwiftMessages {
}
}
- @MainActor
fileprivate func dequeueNext() {
guard queue.count > 0 else { return }
if let _current, !_current.isOrphaned { return }
@@ -645,7 +635,6 @@ open class SwiftMessages {
}
}
- @MainActor
fileprivate func internalHide(presenter: Presenter) {
if presenter == _current {
hideCurrent()
@@ -655,7 +644,6 @@ open class SwiftMessages {
}
}
- @MainActor
fileprivate func hideCurrent(animated: Bool = true) {
guard let current = _current, !current.isHiding else { return }
let action = { [weak self] in
@@ -675,7 +663,6 @@ open class SwiftMessages {
fileprivate weak var autohideToken: Presenter?
- @MainActor
fileprivate func queueAutoHide() {
guard let current = _current else { return }
autohideToken = current
@@ -718,7 +705,6 @@ extension SwiftMessages {
- Parameter id: The id of a message that adopts `Identifiable`.
- Returns: The view with matching id if currently being shown or hidden.
*/
- @MainActor
public func current(id: String) -> T? {
_current?.id == id ? _current?.view as? T : nil
}
@@ -729,7 +715,6 @@ extension SwiftMessages {
- Parameter id: The id of a message that adopts `Identifiable`.
- Returns: The view with matching id if currently queued to be shown.
*/
- @MainActor
public func queued(id: String) -> T? {
queue.first { $0.id == id }?.view as? T
}
@@ -741,7 +726,6 @@ extension SwiftMessages {
- Parameter id: The id of a message that adopts `Identifiable`.
- Returns: The view with matching id if currently queued to be shown.
*/
- @MainActor
public func currentOrQueued(id: String) -> T? {
return current(id: id) ?? queued(id: id)
}
@@ -753,12 +737,10 @@ extension SwiftMessages {
extension SwiftMessages: PresenterDelegate {
- @MainActor
func hide(presenter: Presenter) {
self.internalHide(presenter: presenter)
}
- @MainActor
public func hide(animator: Animator) {
guard let presenter = self.presenter(forAnimator: animator) else { return }
self.internalHide(presenter: presenter)
@@ -768,12 +750,10 @@ extension SwiftMessages: PresenterDelegate {
autohideToken = nil
}
- @MainActor
public func panEnded(animator: Animator) {
queueAutoHide()
}
- @MainActor
private func presenter(forAnimator animator: Animator) -> Presenter? {
if let current = _current, animator === current.animator {
return current
@@ -885,45 +865,38 @@ extension SwiftMessages {
a set of static APIs that wrap calls to this instance. For example, `SwiftMessages.show()`
is equivalent to `SwiftMessages.sharedInstance.show()`.
*/
- @MainActor
- public static var sharedInstance: SwiftMessages {
+ nonisolated public static var sharedInstance: SwiftMessages {
return globalInstance
}
- nonisolated public static func show(viewProvider: @escaping ViewProvider) {
+ public static func show(viewProvider: @escaping ViewProvider) {
globalInstance.show(viewProvider: viewProvider)
}
- nonisolated public static func show(config: Config, viewProvider: @escaping ViewProvider) {
+ public static func show(config: Config, viewProvider: @escaping ViewProvider) {
globalInstance.show(config: config, viewProvider: viewProvider)
}
- @MainActor
public static func show(view: UIView) {
globalInstance.show(view: view)
}
- @MainActor
public static func show(config: Config, view: UIView) {
globalInstance.show(config: config, view: view)
}
- @MainActor
public static func hide(animated: Bool = true) {
globalInstance.hide(animated: animated)
}
- @MainActor
public static func hideAll() {
globalInstance.hideAll()
}
- @MainActor
public static func hide(id: String) {
globalInstance.hide(id: id)
}
- @MainActor
public static func hideCounted(id: String) {
globalInstance.hideCounted(id: id)
}
@@ -946,17 +919,14 @@ extension SwiftMessages {
}
}
- @MainActor
public static func current(id: String) -> T? {
return globalInstance.current(id: id)
}
- @MainActor
public static func queued(id: String) -> T? {
return globalInstance.queued(id: id)
}
- @MainActor
public static func currentOrQueued(id: String) -> T? {
return globalInstance.currentOrQueued(id: id)
}
From b3bccca835fa3533b6789c0af34d5b46454133dc Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Fri, 2 Aug 2024 18:46:36 -0500
Subject: [PATCH 33/38] Fix broken SwiftUI touch handling in iOS 18
---
SwiftMessages/MessageHostingView.swift | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/SwiftMessages/MessageHostingView.swift b/SwiftMessages/MessageHostingView.swift
index b4634d9..f0aaecd 100644
--- a/SwiftMessages/MessageHostingView.swift
+++ b/SwiftMessages/MessageHostingView.swift
@@ -44,10 +44,25 @@ public class MessageHostingView: UIView, Identifiable where Content: Vi
}
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
- let view = super.hitTest(point, with: event)
- // The rendered SwiftUI view isn't a direct child of this hosting view. SwiftUI
- // inserts another intermediate view that should also ignore touches.
- if view == self || view?.superview == self { return nil }
+ guard let view = super.hitTest(point, with: event) else { return nil }
+ // Touches should pass through unless they land on a view that is rendering a SwiftUI element.
+ if view == self { return nil }
+ // In iOS 18 beta, the hit testing behavior changed in a weird way: when a SwiftUI element is tapped,
+ // the first hit test returns the view that renders the SwiftUI element. However, a second identical hit
+ // test is performed(!) and on the second test, the `UIHostingController`'s view is returned. We want touches
+ // to pass through that view. In iOS 17, we would just return `nil` in that case. However, in iOS 18, the
+ // second hit test is actuall essential to touches being delivered to the SwiftUI elements. The new approach
+ // is to iterate overall all of the subviews, which are all presumably rendering SwiftUI elements, and
+ // only return `nil` if the point is not inside any of these subviews.
+ if view.superview == self {
+ for subview in view.subviews {
+ let subviewPoint = self.convert(point, to: subview)
+ if subview.point(inside: subviewPoint, with: event) {
+ return view
+ }
+ }
+ return nil
+ }
return view
}
From 5500236e0942febd2ba865a72c73af9c48633eb3 Mon Sep 17 00:00:00 2001
From: "linpeng.dev" <540933120@qq.com>
Date: Mon, 12 Aug 2024 22:03:53 +0800
Subject: [PATCH 34/38] SwiftMessages.Config expands the popupPriority property
to support the popup queue to accurately control the display order according
to the weight (#555)
---
SwiftMessages/Presenter.swift | 2 +-
SwiftMessages/SwiftMessages.swift | 16 ++++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/SwiftMessages/Presenter.swift b/SwiftMessages/Presenter.swift
index 667d1eb..2010f22 100644
--- a/SwiftMessages/Presenter.swift
+++ b/SwiftMessages/Presenter.swift
@@ -15,7 +15,7 @@ protocol PresenterDelegate: AnimationDelegate {
@MainActor
class Presenter: NSObject {
-
+
// MARK: - API
init(config: SwiftMessages.Config, view: UIView, delegate: PresenterDelegate) {
diff --git a/SwiftMessages/SwiftMessages.swift b/SwiftMessages/SwiftMessages.swift
index 0280bbe..7170965 100644
--- a/SwiftMessages/SwiftMessages.swift
+++ b/SwiftMessages/SwiftMessages.swift
@@ -393,6 +393,11 @@ open class SwiftMessages {
Supply an instance of `KeyboardTrackingView` to have the message view avoid the keyboard.
*/
public var keyboardTrackingView: KeyboardTrackingView?
+
+ /**
+ Specify a positive or negative priority to influence the position of a message in the queue based on it's relative priority.
+ */
+ public var priority: Int = 0
}
/**
@@ -612,6 +617,17 @@ open class SwiftMessages {
fileprivate func dequeueNext() {
guard queue.count > 0 else { return }
if let _current, !_current.isOrphaned { return }
+ // Sort by priority
+ queue = queue.enumerated().sorted { left, right in
+ // The priority is sorted first
+ let leftPriority = left.element.config.priority
+ let rightPriority = right.element.config.priority
+ if leftPriority != rightPriority {
+ return leftPriority > rightPriority
+ }
+ // The same priority is sorted in queue order
+ return left.offset < right.offset
+ }.map { $0.element }
let current = queue.removeFirst()
self._current = current
// Set `autohideToken` before the animation starts in case
From 438a2740988e82b55d4a1bf4532a566d7923036e Mon Sep 17 00:00:00 2001
From: Timothy Moose
Date: Mon, 12 Aug 2024 16:57:37 -0500
Subject: [PATCH 35/38] SwiftUI layout improvement (#560)
---
SwiftMessages.xcodeproj/project.pbxproj | 8 +-
SwiftMessages/MessageGeometryProxy.swift | 17 +
SwiftMessages/MessageHostingView.swift | 43 +-
SwiftMessages/PhysicsAnimation.swift | 58 +-
SwiftMessages/SwiftMessageModifier.swift | 49 +-
iMessageDemo/Podfile.lock | 6 +-
.../Local Podspecs/SwiftMessages.podspec.json | 8 +-
iMessageDemo/Pods/Manifest.lock | 6 +-
.../Pods/Pods.xcodeproj/project.pbxproj | 1242 +++++++++--------
.../Pods-iMessageDemo-Info.plist | 2 +-
.../Pods-iMessageDemo-frameworks.sh | 5 +-
.../Pods-iMessageDemo.debug.xcconfig | 3 +-
.../Pods-iMessageDemo.release.xcconfig | 3 +-
.../Pods-iMessageExtensionDemo-Info.plist | 2 +-
.../Pods-iMessageExtensionDemo.debug.xcconfig | 3 +-
...ods-iMessageExtensionDemo.release.xcconfig | 3 +-
...ges_SwiftMessages-SwiftMessages-Info.plist | 4 +-
.../SwiftMessages/SwiftMessages-Info.plist | 4 +-
.../SwiftMessages.debug.xcconfig | 2 +
.../SwiftMessages.release.xcconfig | 2 +
.../iMessageDemo.xcodeproj/project.pbxproj | 7 +-
21 files changed, 825 insertions(+), 652 deletions(-)
create mode 100644 SwiftMessages/MessageGeometryProxy.swift
diff --git a/SwiftMessages.xcodeproj/project.pbxproj b/SwiftMessages.xcodeproj/project.pbxproj
index 066f5c7..1038482 100644
--- a/SwiftMessages.xcodeproj/project.pbxproj
+++ b/SwiftMessages.xcodeproj/project.pbxproj
@@ -10,6 +10,7 @@
0797E40E26EE12B400691606 /* WindowScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0797E40D26EE12B400691606 /* WindowScene.swift */; };
220655121FAF82B600F4E00F /* MarginAdjustable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */; };
220D386E2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 220D386D2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift */; };
+ 223DE69D2C29E50C000161E5 /* MessageGeometryProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 223DE69C2C29E50B000161E5 /* MessageGeometryProxy.swift */; };
224C3C902C28A2F900B50B18 /* TopBottomPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 224C3C8F2C28A2F900B50B18 /* TopBottomPresentable.swift */; };
224C3C932C28BC4900B50B18 /* TopBottomAnimationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 224C3C922C28BC4400B50B18 /* TopBottomAnimationStyle.swift */; };
224FB69921153B440081D4DE /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 224FB69821153B440081D4DE /* CALayer+Extensions.swift */; };
@@ -105,6 +106,7 @@
0797E40D26EE12B400691606 /* WindowScene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowScene.swift; sourceTree = ""; };
220655111FAF82B600F4E00F /* MarginAdjustable+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MarginAdjustable+Extensions.swift"; sourceTree = ""; };
220D386D2597AA5B00BB2B88 /* SwiftMessages.Config+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SwiftMessages.Config+Extensions.swift"; sourceTree = ""; };
+ 223DE69C2C29E50B000161E5 /* MessageGeometryProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageGeometryProxy.swift; sourceTree = ""; };
224C3C8F2C28A2F900B50B18 /* TopBottomPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBottomPresentable.swift; sourceTree = ""; };
224C3C922C28BC4400B50B18 /* TopBottomAnimationStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBottomAnimationStyle.swift; sourceTree = ""; };
224FB69821153B440081D4DE /* CALayer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Extensions.swift"; sourceTree = ""; };
@@ -253,8 +255,10 @@
228F7DDA2ACF7029006C9644 /* SwiftUI */ = {
isa = PBXGroup;
children = (
- 228F7DDC2ACF703A006C9644 /* SwiftMessageModifier.swift */,
+ 223DE69C2C29E50B000161E5 /* MessageGeometryProxy.swift */,
+ 228F7DDB2ACF7039006C9644 /* MessageHostingView.swift */,
228F7DDD2ACF703A006C9644 /* MessageViewConvertible.swift */,
+ 228F7DDC2ACF703A006C9644 /* SwiftMessageModifier.swift */,
);
name = SwiftUI;
sourceTree = "";
@@ -366,7 +370,6 @@
86AAF8171D54F0650031EE32 /* PassthroughView.swift */,
22E01F631E74EC8B00ACE19A /* MaskingView.swift */,
86AAF8191D54F0850031EE32 /* PassthroughWindow.swift */,
- 228F7DDB2ACF7039006C9644 /* MessageHostingView.swift */,
220D38672597A94C00BB2B88 /* Extensions */,
);
name = Internal;
@@ -597,6 +600,7 @@
86589D471D64B6E40041676C /* BaseView.swift in Sources */,
0797E40E26EE12B400691606 /* WindowScene.swift in Sources */,
225304622290C76E00A03ACF /* NSLayoutConstraint+Extensions.swift in Sources */,
+ 223DE69D2C29E50C000161E5 /* MessageGeometryProxy.swift in Sources */,
86BBA9071D5E040C00FE8F16 /* MarginAdjustable.swift in Sources */,
867BED211D622793005212E3 /* BackgroundViewable.swift in Sources */,
);
diff --git a/SwiftMessages/MessageGeometryProxy.swift b/SwiftMessages/MessageGeometryProxy.swift
new file mode 100644
index 0000000..73d2d78
--- /dev/null
+++ b/SwiftMessages/MessageGeometryProxy.swift
@@ -0,0 +1,17 @@
+//
+// MessageGeometryProxy.swift
+// SwiftMessages
+//
+// Created by Timothy Moose on 6/24/24.
+// Copyright © 2024 SwiftKick Mobile. All rights reserved.
+//
+
+import SwiftUI
+
+/// A data type that mimicks `GeomtryProxy` and is used with `swiftMessage()` modifier when the geomtry metrics of the container view
+/// are needed, particularly because `GeometryReader` doesn't work inside the view builder due to the way the message view is being
+/// displayed from UIKit.
+public struct MessageGeometryProxy {
+ public var size: CGSize
+ public var safeAreaInsets: EdgeInsets
+}
diff --git a/SwiftMessages/MessageHostingView.swift b/SwiftMessages/MessageHostingView.swift
index f0aaecd..4301090 100644
--- a/SwiftMessages/MessageHostingView.swift
+++ b/SwiftMessages/MessageHostingView.swift
@@ -17,13 +17,20 @@ public class MessageHostingView: UIView, Identifiable where Content: Vi
public let id: String
public init(id: String, content: Content) {
- hostVC = UIHostingController(rootView: content)
self.id = id
+ self.content = { _ in content }
+ super.init(frame: .zero)
+ backgroundColor = .clear
+ }
+
+ public init(
+ message: Message,
+ @ViewBuilder content: @escaping (Message, MessageGeometryProxy) -> Content
+ ) where Message: Identifiable {
+ self.id = message.id
+ self.content = { geom in content(message, geom) }
super.init(frame: .zero)
- hostVC.loadViewIfNeeded()
- installContentView(hostVC.view)
backgroundColor = .clear
- hostVC.view.backgroundColor = .clear
}
convenience public init(message: Message) where Message: MessageViewConvertible, Message.Content == Content {
@@ -34,7 +41,8 @@ public class MessageHostingView: UIView, Identifiable where Content: Vi
// MARK: - Variables
- private let hostVC: UIHostingController
+ private var hostVC: UIHostingController?
+ private let content: (MessageGeometryProxy) -> Content
// MARK: - Lifecycle
@@ -66,6 +74,31 @@ public class MessageHostingView: UIView, Identifiable where Content: Vi
return view
}
+ public override func didMoveToSuperview() {
+ guard let superview = self.superview else { return }
+ let size = superview.bounds.size
+ let insets = superview.safeAreaInsets
+ let ltr = superview.effectiveUserInterfaceLayoutDirection == .leftToRight
+ let proxy = MessageGeometryProxy(
+ size: CGSize(
+ width: size.width - insets.left - insets.right,
+ height: size.height - insets.top - insets.bottom
+ ),
+ safeAreaInsets: EdgeInsets(
+ top: insets.top,
+ leading: ltr ? insets.left : insets.right,
+ bottom: insets.bottom,
+ trailing: ltr ? insets.right : insets.left
+ )
+ )
+ let hostVC = UIHostingController(rootView: content(proxy))
+ self.hostVC = hostVC
+ hostVC.loadViewIfNeeded()
+ installContentView(hostVC.view)
+ hostVC.view.backgroundColor = .clear
+
+ }
+
// MARK: - Configuration
private func installContentView(_ contentView: UIView) {
diff --git a/SwiftMessages/PhysicsAnimation.swift b/SwiftMessages/PhysicsAnimation.swift
index 5f5ecaf..ef8476f 100644
--- a/SwiftMessages/PhysicsAnimation.swift
+++ b/SwiftMessages/PhysicsAnimation.swift
@@ -37,7 +37,12 @@ public class PhysicsAnimation: NSObject, Animator {
}
public func show(context: AnimationContext, completion: @escaping AnimationCompletion) {
- NotificationCenter.default.addObserver(self, selector: #selector(adjustMargins), name: UIDevice.orientationDidChangeNotification, object: nil)
+ NotificationCenter.default.addObserver(
+ self,
+ selector: #selector(adjustMargins),
+ name: UIDevice.orientationDidChangeNotification,
+ object: nil
+ )
install(context: context)
showAnimation(context: context, completion: completion)
}
@@ -56,12 +61,24 @@ public class PhysicsAnimation: NSObject, Animator {
view.transform = CGAffineTransform.identity
completion(true)
}
- UIView.animate(withDuration: hideDuration, delay: 0, options: [.beginFromCurrentState, .curveEaseIn, .allowUserInteraction], animations: {
- view.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
- }, completion: nil)
- UIView.animate(withDuration: hideDuration, delay: 0, options: [.beginFromCurrentState, .curveEaseIn, .allowUserInteraction], animations: {
- view.alpha = 0
- }, completion: nil)
+ UIView.animate(
+ withDuration: hideDuration,
+ delay: 0,
+ options: [.beginFromCurrentState, .curveEaseIn, .allowUserInteraction],
+ animations: {
+ view.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
+ },
+ completion: nil
+ )
+ UIView.animate(
+ withDuration: hideDuration,
+ delay: 0,
+ options: [.beginFromCurrentState, .curveEaseIn, .allowUserInteraction],
+ animations: {
+ view.alpha = 0
+ },
+ completion: nil
+ )
CATransaction.commit()
}
@@ -75,14 +92,31 @@ public class PhysicsAnimation: NSObject, Animator {
container.addSubview(view)
switch placement {
case .center:
- view.centerYAnchor.constraint(equalTo: container.centerYAnchor).with(priority: UILayoutPriority(200)).isActive = true
+ view.centerYAnchor.constraint(
+ equalTo: container.centerYAnchor
+ )
+ .with(priority: UILayoutPriority(200))
+ .isActive = true
case .top:
- view.topAnchor.constraint(equalTo: container.topAnchor).with(priority: UILayoutPriority(200)).isActive = true
+ view.topAnchor.constraint(
+ equalTo: container.topAnchor
+ )
+ .with(priority: UILayoutPriority(200))
+ .isActive = true
case .bottom:
- view.bottomAnchor.constraint(equalTo: container.bottomAnchor).with(priority: UILayoutPriority(200)).isActive = true
+ view.bottomAnchor.constraint(
+ equalTo: container.bottomAnchor
+ )
+ .with(priority: UILayoutPriority(200))
+ .isActive = true
}
- NSLayoutConstraint(item: view, attribute: .leading, relatedBy: .equal, toItem: container, attribute: .leading, multiplier: 1, constant: 0).isActive = true
- NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: container, attribute: .trailing, multiplier: 1, constant: 0).isActive = true
+ NSLayoutConstraint.activate([
+ view.leadingAnchor.constraint(equalTo: container.leadingAnchor),
+ view.trailingAnchor.constraint(equalTo: container.trailingAnchor),
+ // Don't allow the message to spill outside of the top or bottom of the container.
+ view.topAnchor.constraint(greaterThanOrEqualTo: container.topAnchor),
+ view.bottomAnchor.constraint(lessThanOrEqualTo: container.bottomAnchor),
+ ])
// Important to layout now in order to get the right safe area insets
container.layoutIfNeeded()
adjustMargins()
diff --git a/SwiftMessages/SwiftMessageModifier.swift b/SwiftMessages/SwiftMessageModifier.swift
index 3cab498..e44d687 100644
--- a/SwiftMessages/SwiftMessageModifier.swift
+++ b/SwiftMessages/SwiftMessageModifier.swift
@@ -9,15 +9,36 @@ import SwiftUI
@available(iOS 14.0, *)
public extension View {
- /// A state-based modifier for displaying a message when `Message` does not conform to `MessageViewConvertible`. This variant is more flexible and
- /// should be used if the message view can't be represented as pure data, such as if it requires a delegate, has callbacks, etc.
+ /// A view modifier for displaying a message using similar semantics to the `.sheet()` modifier.
func swiftMessage(
message: Binding,
config: SwiftMessages.Config? = nil,
swiftMessages: SwiftMessages? = nil,
@ViewBuilder messageContent: @escaping (Message) -> MessageContent
) -> some View where Message: Equatable & Identifiable, MessageContent: View {
- modifier(SwiftMessageModifier(message: message, config: config, swiftMessages: swiftMessages, messageContent: messageContent))
+ swiftMessage(message: message, config: config, swiftMessages: swiftMessages) { message, _ in
+ messageContent(message)
+ }
+ }
+
+ /// A view modifier for displaying a message using similar semantics to the `.sheet()` modifier. This variant provides a
+ /// `SwiftMessageGeometryProxy`. The proxy is useful when one needs to know the geometry metrics of the container view,
+ /// particularly because `GeometryReader` doesn't work inside the view builder due to the way the message view is being
+ /// displayed from UIKit.
+ func swiftMessage(
+ message: Binding,
+ config: SwiftMessages.Config? = nil,
+ swiftMessages: SwiftMessages? = nil,
+ @ViewBuilder messageContent: @escaping (Message, MessageGeometryProxy) -> MessageContent
+ ) -> some View where Message: Equatable & Identifiable, MessageContent: View {
+ modifier(
+ SwiftMessageModifier(
+ message: message,
+ config: config,
+ swiftMessages: swiftMessages,
+ messageContent: messageContent
+ )
+ )
}
/// A state-based modifier for displaying a message when `Message` conforms to `MessageViewConvertible`. This variant should be used if the message
@@ -43,6 +64,20 @@ private struct SwiftMessageModifier: ViewModifier where
config: SwiftMessages.Config? = nil,
swiftMessages: SwiftMessages? = nil,
@ViewBuilder messageContent: @escaping (Message) -> MessageContent
+ ) {
+ _message = message
+ self.config = config
+ self.swiftMessages = swiftMessages
+ self.messageContent = { message, _ in
+ messageContent(message)
+ }
+ }
+
+ fileprivate init(
+ message: Binding,
+ config: SwiftMessages.Config? = nil,
+ swiftMessages: SwiftMessages? = nil,
+ @ViewBuilder messageContent: @escaping (Message, MessageGeometryProxy) -> MessageContent
) {
_message = message
self.config = config
@@ -58,7 +93,9 @@ private struct SwiftMessageModifier: ViewModifier where
_message = message
self.config = config
self.swiftMessages = swiftMessages
- self.messageContent = { $0.asMessageView() }
+ self.messageContent = { message, _ in
+ message.asMessageView()
+ }
}
// MARK: - Constants
@@ -68,7 +105,7 @@ private struct SwiftMessageModifier: ViewModifier where
@Binding private var message: Message?
private let config: SwiftMessages.Config?
private let swiftMessages: SwiftMessages?
- @ViewBuilder private let messageContent: (Message) -> MessageContent
+ @ViewBuilder private let messageContent: (Message, MessageGeometryProxy) -> MessageContent
// MARK: - Body
@@ -79,7 +116,7 @@ private struct SwiftMessageModifier: ViewModifier where
let hideAll: @MainActor () -> Void = swiftMessages?.hideAll ?? SwiftMessages.hideAll
switch message {
case let message?:
- let view = MessageHostingView(id: message.id, content: messageContent(message))
+ let view = MessageHostingView(message: message, content: messageContent)
var config = config ?? swiftMessages?.defaultConfig ?? SwiftMessages.defaultConfig
config.eventListeners.append { event in
if case .didHide = event, event.id == self.message?.id {
diff --git a/iMessageDemo/Podfile.lock b/iMessageDemo/Podfile.lock
index 7162a91..400dd99 100644
--- a/iMessageDemo/Podfile.lock
+++ b/iMessageDemo/Podfile.lock
@@ -1,5 +1,5 @@
PODS:
- - SwiftMessages/AppExtension (9.0.3)
+ - SwiftMessages/AppExtension (10.0.1)
DEPENDENCIES:
- SwiftMessages/AppExtension (from `../`)
@@ -9,8 +9,8 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
- SwiftMessages: 077f19126c24033fe24042237ecc20261adb46e4
+ SwiftMessages: 759b4a0bf5c3a116a0d7e8a34b098ba83c458625
PODFILE CHECKSUM: 2eb9a33592d0c52131c37a9dd169a8c4604ffd7b
-COCOAPODS: 1.10.1
+COCOAPODS: 1.15.2
diff --git a/iMessageDemo/Pods/Local Podspecs/SwiftMessages.podspec.json b/iMessageDemo/Pods/Local Podspecs/SwiftMessages.podspec.json
index 6d9e93c..a117b2d 100644
--- a/iMessageDemo/Pods/Local Podspecs/SwiftMessages.podspec.json
+++ b/iMessageDemo/Pods/Local Podspecs/SwiftMessages.podspec.json
@@ -1,20 +1,20 @@
{
"name": "SwiftMessages",
- "version": "9.0.3",
+ "version": "10.0.1",
"license": {
"type": "MIT"
},
"homepage": "https://github.com/SwiftKickMobile/SwiftMessages",
"authors": {
- "Timothy Moose": "tim@swiftkick.it"
+ "Timothy Moose": "tim@swiftkickmobile.com"
},
"summary": "A very flexible message bar for iOS written in Swift.",
"source": {
"git": "https://github.com/SwiftKickMobile/SwiftMessages.git",
- "tag": "9.0.3"
+ "tag": "10.0.1"
},
"platforms": {
- "ios": "9.0"
+ "ios": "13.0"
},
"swift_versions": "5.0",
"frameworks": "UIKit",
diff --git a/iMessageDemo/Pods/Manifest.lock b/iMessageDemo/Pods/Manifest.lock
index 7162a91..400dd99 100644
--- a/iMessageDemo/Pods/Manifest.lock
+++ b/iMessageDemo/Pods/Manifest.lock
@@ -1,5 +1,5 @@
PODS:
- - SwiftMessages/AppExtension (9.0.3)
+ - SwiftMessages/AppExtension (10.0.1)
DEPENDENCIES:
- SwiftMessages/AppExtension (from `../`)
@@ -9,8 +9,8 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
- SwiftMessages: 077f19126c24033fe24042237ecc20261adb46e4
+ SwiftMessages: 759b4a0bf5c3a116a0d7e8a34b098ba83c458625
PODFILE CHECKSUM: 2eb9a33592d0c52131c37a9dd169a8c4604ffd7b
-COCOAPODS: 1.10.1
+COCOAPODS: 1.15.2
diff --git a/iMessageDemo/Pods/Pods.xcodeproj/project.pbxproj b/iMessageDemo/Pods/Pods.xcodeproj/project.pbxproj
index 0d6bbc2..cf4122e 100644
--- a/iMessageDemo/Pods/Pods.xcodeproj/project.pbxproj
+++ b/iMessageDemo/Pods/Pods.xcodeproj/project.pbxproj
@@ -3,111 +3,119 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 50;
+ objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
- 00764FFD14D83F4ABEC0D4D53D48080A /* SwiftMessages-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C6E00017F9E79F6D4926E9CB43A66DF /* SwiftMessages-dummy.m */; };
- 02905CCF79B22A773CD0BA32EDB9648A /* AccessibleMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0201BC51C7CA061016B619400691A139 /* AccessibleMessage.swift */; };
- 05D9CBEC9488BAA2962B174703D25218 /* PassthroughWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A331C2E0BE2AE2118D65AA1F12519F2 /* PassthroughWindow.swift */; };
- 0C55441C4B8356AC1244EED7684E1783 /* MaskingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D69BE188B82D84ED23AC4E27BAB61D /* MaskingView.swift */; };
- 11DE7052A0A78D6E27D8D129D413DAF6 /* errorIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 7100245A2722BD53D5B3927ED649069F /* errorIconLight.png */; };
- 13620BA62A66C8C6F9345341BCD111ED /* KeyboardTrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90AC342C6F09BF7715D4FB95512DD68A /* KeyboardTrackingView.swift */; };
- 1662CF43016AFC375200E466F130D90E /* warningIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = 860D833A7A1B108A89ED34AD74778AC0 /* warningIconSubtle.png */; };
- 28F2E02536C48A4B661D6D8AAFB5D37E /* CornerRoundingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 007ACA6F89C6C856F78352A086F3B8EA /* CornerRoundingView.swift */; };
- 30D023ABC2D1CFC829CF04360768B7F8 /* StatusLine.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1E2FE4DB6869F330F19A3A5459AAFFFB /* StatusLine.xib */; };
- 34CB62900FA4AAC84745C7E958657648 /* errorIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D30B2BF71F9D2C63C2D202C99827CDC1 /* errorIconLight@2x.png */; };
- 3A8B97D9210D1E2BEED5E1159BE7E748 /* warningIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = C56AB83FDAB8D6A1328E7EECCAD99A69 /* warningIconLight.png */; };
- 3BFC9F0FAF0757A2D3574ED4E4100D57 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 467EAD44C7F625F384822180F004E64F /* CALayer+Extensions.swift */; };
- 4256FC87C833154DCDEE84CD98F910D7 /* Identifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFD31968BF9DF7A9E25A136DF254F3A9 /* Identifiable.swift */; };
- 46CCA4DDFDBBDD2A9426BB96C08E4255 /* Pods-iMessageExtensionDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F40CA14AD738DD186B4DA8FD14AE5BD /* Pods-iMessageExtensionDemo-dummy.m */; };
- 47F1E9964F1112D0E8F0FF8C25204E2F /* SwiftMessages_SwiftMessages.bundle in Resources */ = {isa = PBXBuildFile; fileRef = BEBF018059B0DFCAC8494ABD1C578AD9 /* SwiftMessages_SwiftMessages.bundle */; };
- 4889E21A2024267A944084FB851200B5 /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7EE64CFE0084CF5213A03AF29A668ED /* BaseView.swift */; };
- 4B907B48F27F55DF65CC1553C7C26942 /* infoIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 730840765E737D45772EBE66DB8A6D2E /* infoIconLight.png */; };
- 4B9459A11E2A1D65AE3224CF468AE8CA /* warningIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7C4DF53A4B44C246968618BF25962786 /* warningIconLight@3x.png */; };
- 4E82DE4069FECF20D0E29CB06A0FCFB6 /* SwiftMessages.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6264350B8D100D5B5C5EEEC316933D /* SwiftMessages.swift */; };
- 531825CE7041C5C1BA684BDA9C8972A3 /* UIEdgeInsets+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36F7B24601DF4C00B14EC8CE2D4A48DC /* UIEdgeInsets+Extensions.swift */; };
- 560A2B1056FEFE42AC6524A2A1742CA2 /* Pods-iMessageExtensionDemo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAB201AD00CAB811B045E2FFB5C03A8 /* Pods-iMessageExtensionDemo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 56F9865D99C4FADB8FC83CA548F82110 /* successIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 17ADABD24F805C5F7FF62167E7ABEF0A /* successIconSubtle@3x.png */; };
- 5B9F8D117AF7BEDDB511EF475FA25995 /* infoIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 48DC3BADDA3A20F2AEB8585117DAFA0D /* infoIcon@3x.png */; };
- 5CA294C8D3BBC986CF0703D4E2A28687 /* SwiftMessages.Config+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A16E25077F8D76288BE678E6AC1C884 /* SwiftMessages.Config+Extensions.swift */; };
- 61548914728141D77F87E31B3911CE7E /* successIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 91D9224F29E092950BADC27C979E10CC /* successIconSubtle@2x.png */; };
- 62B05E0AC13A614A2F8D8A1BE9B514B3 /* infoIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = F9CDB54E629D60FF881DF27B949F4C2D /* infoIconSubtle.png */; };
- 632538BAE98BBFD6CED58844B7611C24 /* MarginAdjustable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C8214A441D845A4A4DD6570FD5D458F /* MarginAdjustable+Extensions.swift */; };
- 6685298EC64F73060F5DB1A841375069 /* warningIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8AD355ED684A939F2A4E333F95E8AC31 /* warningIconSubtle@2x.png */; };
- 668EDAB86421216BEF7D3F932851A834 /* errorIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 468D9889455DE51BD5BBC2360BDBB877 /* errorIconSubtle@2x.png */; };
- 6A933CC66558A1FB0AB0BC76F9807E71 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF65ECDAFAD03A79B5571C6F66D8F35 /* TopBottomAnimation.swift */; };
- 755898E0E511FC5AE881403BEF2A02FC /* successIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D032FCFAE6607CF878AA2F35EF93146C /* successIcon@3x.png */; };
- 7905F28CF56E06626475EBA3EB73D905 /* MarginAdjustable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68834C60D0C5EA751E9F12E427C5FFE /* MarginAdjustable.swift */; };
- 7B352022AFCAA5C364E1E2F61290628E /* MessageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B8A4CCB4B08D2D3BE586212AB4167DC2 /* MessageView.xib */; };
- 7BC52E6F0D9D19B05E62E623E53FCE82 /* Pods-iMessageDemo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D0ECE831FB5E0EE1D68E837671320C7 /* Pods-iMessageDemo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 80DE92140CF5AFB5224643FA952EFDEA /* successIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 52F1CA85E0EED7D94FE0036BC92EB3EC /* successIconLight.png */; };
- 8F1BAB73C85D58C56F55E91573C2E7EF /* infoIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = E41BFEB1BFF85793C0DB85F95184B752 /* infoIcon.png */; };
- 926907C8DCE76101AF5CB470DB7797D7 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88D73E42D996B226222A4EBA46F7DC6D /* Weak.swift */; };
- 934A8FA91D6518CB70273B73F8038ECA /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 778F6E19CE49B8EDBAC2FCCD8195A55B /* MessageView.swift */; };
- 946185C05E253C9E47ABCD9EDE7E14D1 /* warningIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 29A39558830996C4F54686A1748B74B1 /* warningIcon@2x.png */; };
- 94B459D6CBA2A01D2B8174D138C30920 /* UIWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753B78926D6BB175E96AB6E6F3514E87 /* UIWindow+Extensions.swift */; };
- 95DD12BBA763163407787AB32AAF8E56 /* successIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = A342E145FED9CD8DB4F464D110203E7C /* successIcon.png */; };
- 9B1E91097B4BD539EBCBBCC3C62CB75A /* errorIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = DEC0A6AE07C3285CA508F8FA3F4FE27D /* errorIcon.png */; };
- 9B1F7A4183F57B0AA9DD02624BD8855B /* PhysicsPanHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDEF50CAF615897F7A8540579B445634 /* PhysicsPanHandler.swift */; };
- 9B89868BA12CC4E1D9F116F663E56695 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24021DCE87BE9746D1DFB436C0A3AF7A /* Theme.swift */; };
- 9CFE7FFD7DDE28FCDA72647F2DB82837 /* infoIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 45844D489A130BA91E91E7CDD4969862 /* infoIconSubtle@2x.png */; };
- 9DA2F2EED5C99045AF44FF410A012F9D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
- 9DBD1955C7C621D9DCBE03D2161C91A9 /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D261B7BE0088C26BF6744F27B894492A /* UIViewController+Extensions.swift */; };
- 9F0473806FD530165403E47E834790C2 /* CenteredView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 787EE6DA4FBC3BF85ED2CF0BB6EBF494 /* CenteredView.xib */; };
- 9FA48348FB5F41070356A75237367D6D /* TabView.xib in Resources */ = {isa = PBXBuildFile; fileRef = EABF0CEB87991D02E13306975A8E80BB /* TabView.xib */; };
- A67A9ADFBCB364FCEF1BD92FF20B285C /* CardView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 705B5AF043D00B6538599B4EB1ECD77C /* CardView.xib */; };
- A9EB0C8E49AB748B05CF7941ACAF8475 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
- A9FFA668A7F81F50FBDCDCE26E891C8B /* errorIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = E0E4D99C4F78B9BA011D83FE63EE0946 /* errorIcon@3x.png */; };
- AC0A9B473B11FFF4BDEC0A0598795843 /* WindowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AA0E820F1C1AA219C066370332845A /* WindowViewController.swift */; };
- AD7F228AE0628DAAE4497493335D2BF7 /* SwiftMessages-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CBEAC9D0EF4113C3FD3B15F511A92D0 /* SwiftMessages-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- ADA044C43E517C5F0603B2A0AFB19860 /* successIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 760BFB41B33B6ED91B3FFD68D39083A0 /* successIconLight@2x.png */; };
- ADA91E8F5FDCD2EEC3D3B18A5B375C2C /* errorIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DF3DE135AB5C5C789CABAECC704CE907 /* errorIcon@2x.png */; };
- ADE48B746D5BB28EC33B403E1E12E0FE /* infoIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E936107A7CF9821DCBFFAF50D916F1E6 /* infoIcon@2x.png */; };
- AF34F903519AF36E07A90EF1BD703777 /* WindowScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8DEFE9675E5359A46A443182F127F06 /* WindowScene.swift */; };
- B02B2EAB7B8662AA27D91403BF9AAF36 /* warningIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = A0EE84E98A10805A2D64B836C465ED11 /* warningIconSubtle@3x.png */; };
- B4D338F85183163DC8CAB8A5864C9015 /* infoIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 676F359BE8561CF7512DB8B42CD7873A /* infoIconLight@3x.png */; };
- B520EDE98BD17CE5676F52A77139A933 /* NSLayoutConstraint+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6924EB5FC7236837637AE8F409000A /* NSLayoutConstraint+Extensions.swift */; };
- B679ED0F79CAF552C081588F3B63B91A /* warningIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0038C9A582787F9882258E8D1080EACF /* warningIcon@3x.png */; };
- C11CE75FD2DFCDF3B72D8D16280A2054 /* successIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 79D34B3C6875DA0279CB934C84CD000B /* successIcon@2x.png */; };
- C384FB76A48C06F7581D0F7850F2F4F1 /* Pods-iMessageDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 14BF989232A1D55A0FDAAB70B5A8E1BF /* Pods-iMessageDemo-dummy.m */; };
- C3CDAED707B153A58674CB1AC4A33FB2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
- C418A50F3C321227B0C6BE1D793680D4 /* successIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = FA199E6F18AB8900B5400EBA0EB32765 /* successIconLight@3x.png */; };
- C739607C022819840C267A0B4A7B2FD9 /* SwiftMessagesSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF27E3EF103BACDEE8CA842B2C90C8CA /* SwiftMessagesSegue.swift */; };
- C826D41BE5AF283B12C122AEF9640C99 /* infoIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C9F5DBB6D77B1E61E9BB1A722A4E1823 /* infoIconSubtle@3x.png */; };
- CC9369D0A5F8715733A4D517E45A3B63 /* infoIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8315EA451FE61625920FEF68174A0D22 /* infoIconLight@2x.png */; };
- CD480EEF400EC9B894F3292506BF0179 /* successIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = B031268635405AA009D05130C0FC253C /* successIconSubtle.png */; };
- D34D8255545B84A38C98D2DBB2F12CC5 /* PassthroughView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E03CBB908F2EC39AA5DA7AF04E1BDDD6 /* PassthroughView.swift */; };
- DE23509CED3A1E62F60E7E4BD6D38A35 /* BackgroundViewable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C706F1F1C6B3CE84445485C8577D5388 /* BackgroundViewable.swift */; };
- DECF1F62709D95EF5B48628A97B3CF98 /* warningIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 3259F99D03B6D738D7F47A625E7BD3BE /* warningIcon.png */; };
- E70A6E572A6DD457A766908E3ADCF49B /* errorIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = C787DA4E67B952C984FF5B065E0A2FF7 /* errorIconSubtle.png */; };
- E8174481BFB4559462F82062D85C0376 /* warningIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FFB0D50D01FFFA3FC2099E395029AE68 /* warningIconLight@2x.png */; };
- ECE268E9A63198F53B3F0337B3EA8AF3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D245E0514AAC1A2B9A6D5EA2F383E90F /* UIKit.framework */; };
- F05B5437AFF475FE8811E2A8A734920F /* NSBundle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E2EB968B30DE56F38B5FCFFEDE9F88F /* NSBundle+Extensions.swift */; };
- F4BE83FBD5001DEDF6736E69ADA6D79B /* Presenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F513F2674553CBC247EE4B24EA25C99C /* Presenter.swift */; };
- F69D9D53A5500A42D4B41097537628E5 /* errorIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = E31D045D9E355D4F7F75564026B2051A /* errorIconSubtle@3x.png */; };
- F75A8D3DA9B4787BEEEBF3F784D5CDEF /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D219D80184B8ED97808EE17507B213A /* Animator.swift */; };
- F9A111F30C3B26D0A35B0829EED70D26 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5E610C06F5B006DE57F34D5994532FB /* Error.swift */; };
- FA02B47E32DD9BEAAB8A2D1B66F697D5 /* PhysicsAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D2B448BE319CF56A38E222C0B7DF4CB /* PhysicsAnimation.swift */; };
- FDC2C20416D7EBF959A461E25FAFB16E /* errorIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D34E3F2A49E9024A96334DA4147F27B /* errorIconLight@3x.png */; };
+ 00A4A53E0D1EFC70DA1EFAEFA82C4BA1 /* Weak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 442F9FAEDF369CADB9E6E8FF3668FD95 /* Weak.swift */; };
+ 03C7FA1BE62CCD280D63F4C7CDDFB27F /* AccessibleMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E8A4D41E0A0E52C839F7197C4CE2A0 /* AccessibleMessage.swift */; };
+ 04BCE3C12FDE7E91C9EF1FE154E80E2B /* SwiftMessageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B19DACBEC8DD85FB850D299DFB7A0374 /* SwiftMessageModifier.swift */; };
+ 04C771EB4784B94AC6CA28ED6A919D50 /* WindowScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB9866F195EB0AED31A33AEC27B67C1 /* WindowScene.swift */; };
+ 096A6663757CB52C8A34B3E3146279C8 /* infoIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2CF5DC74916EBE02E70234620CD80150 /* infoIcon@2x.png */; };
+ 0ADA608E3B9307694DCF4D0BC426E7FE /* warningIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B241F1B5D295E7806363B802DF03A085 /* warningIcon@2x.png */; };
+ 0C093AF5F4D753325F4CE92F2F943CB4 /* MarginAdjustable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14DF8F43552C4F1C4CAEFBAFD9A77004 /* MarginAdjustable.swift */; };
+ 0D53997CCCD141D2303E87C29CEFE211 /* MessageView.xib in Resources */ = {isa = PBXBuildFile; fileRef = A4D741EF8B40F5472CE2C1C1A34426BD /* MessageView.xib */; };
+ 1441D5A06DD6903562EB794FC1AE8822 /* TabView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C33B3DA756F19F5C93D498D557BEB820 /* TabView.xib */; };
+ 158EF18377B720081C31C2F2100DDA7A /* Presenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D18688EA04EA2F2BC48ED05D1FE5404 /* Presenter.swift */; };
+ 19C0F7897044E72D3A13DE703920FFE1 /* MessageHostingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F989D33CAC3BCDA9B3C4B18F23A4DBE /* MessageHostingView.swift */; };
+ 1E507663F3C402CBCA0C50A876F472EF /* errorIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D6A205E933052E98349DC710D78304CB /* errorIconLight@3x.png */; };
+ 205A52121D20436063240893A461B29C /* errorIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 38D28C78FCAE6706F1294CEFA6B25F88 /* errorIconSubtle@2x.png */; };
+ 24DA4886290040A0EC88B63D82EF412D /* warningIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5E02B1554754BA1F8EF318D567875139 /* warningIconSubtle@3x.png */; };
+ 274D5DE28E0446655163A48E2272860A /* CornerRoundingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86872F4639B26435D20BED0CE7E35C7F /* CornerRoundingView.swift */; };
+ 28D6446B971F186BACDED83CD8DE4D44 /* SwiftMessages-SwiftMessages_SwiftMessages in Resources */ = {isa = PBXBuildFile; fileRef = BEBF018059B0DFCAC8494ABD1C578AD9 /* SwiftMessages-SwiftMessages_SwiftMessages */; };
+ 31660027252C457325491844F16AEBDD /* successIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 74793ADC8ADF7674EA6C3041E2B54354 /* successIcon.png */; };
+ 330C59E62D17601422EDB29513B9856C /* SwiftMessages.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC10D7DB2D227D4AA8F41CDFDDC24F37 /* SwiftMessages.swift */; };
+ 3451B2775584DD75A3BDF9BF28A03F76 /* SwiftMessagesSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17EF282E0A0F329DDF17226E83706F8 /* SwiftMessagesSegue.swift */; };
+ 3479628DE3B6C9005316A7F591F5E68F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
+ 360BEE76BBF40319E6638B3E027E1474 /* errorIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = EDFC2E756AAB98672C4B241097AAF0F6 /* errorIconSubtle.png */; };
+ 3613DBA9CBD7E092BD7DC1924E6648D2 /* infoIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = ACCCF5B75EA41D844ED936A92602C5B1 /* infoIconLight@2x.png */; };
+ 37A8DD40AF13BCABE7A3CD8EF15A4C53 /* successIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D146564C0660B5F616D6736F6560E17C /* successIconSubtle@2x.png */; };
+ 3C566158256E9CC711B73810B2C64E3B /* KeyboardTrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A99EE79DBFA3C24A372DDB69162E36C /* KeyboardTrackingView.swift */; };
+ 3F53FCE80C716C7DE7A3B1D8D65077BC /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35F5FB13175EC0E13D53B445CE31395A /* CALayer+Extensions.swift */; };
+ 422B422F962FD298F963F84934A21529 /* infoIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = C3701E97FDB85EFCE90E06D8CBC8ED41 /* infoIconLight.png */; };
+ 436D8C63FBE86FF8271ABC32F9A52A9D /* Pods-iMessageDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 14BF989232A1D55A0FDAAB70B5A8E1BF /* Pods-iMessageDemo-dummy.m */; };
+ 450919BA3A4D984DC24822CD80483419 /* TopBottomPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A102DE8896931D80E06F2C74C2B003AC /* TopBottomPresentable.swift */; };
+ 45A4B95F1F73413A3001B95E1F91D697 /* UIWindow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBC808D0C98F682E01DC43B544ED093F /* UIWindow+Extensions.swift */; };
+ 4609D5EC365EABFE507781BF911B887B /* warningIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 004EE347886E2355CCB352F2AE7A35D6 /* warningIconLight.png */; };
+ 469995B0FC2E3748F59D0E3A4445E197 /* CenteredView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 975A42F4C16B65B38769916EC5468D2A /* CenteredView.xib */; };
+ 47CC2A912B82A499DB2F5E2ADBE664CF /* HapticMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA8BFA921A44ED7AEAA0E08BCE17EDDA /* HapticMessage.swift */; };
+ 47EFB870CC797D2F54396F0AEBC8F576 /* errorIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = EC387534FD34764D4CC28B276A500AD6 /* errorIconLight.png */; };
+ 48ADA8D4633776558E7D216434057A2A /* SwiftMessages.Config+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D83D1CC131CDAC7CA2C5BFD8701E8A79 /* SwiftMessages.Config+Extensions.swift */; };
+ 4980F404C2B391C621CE2BCF05E08BDF /* errorIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C12E87D0EA045A56FC0B45F072C74D2 /* errorIconSubtle@3x.png */; };
+ 4C9FED5D268E82325C17309FB8904C43 /* warningIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B8B9892D8D5596E09F02DA2D71BF60B4 /* warningIcon@3x.png */; };
+ 52A01853AC4F2D0E720579D7F8A531CF /* WindowViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9908774A62A95BF5BA8FE65842868043 /* WindowViewController.swift */; };
+ 60F02D519964FFEE8A21221FF5E0B0C5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
+ 61F532D30833A9FF1DE00EC98BC018C2 /* successIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5686DFC1E0B24A3051EF376AD8A162C0 /* successIconLight@3x.png */; };
+ 634267873AC0F98140DBAFFF9A180BA8 /* MarginAdjustable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B602E4E64DAEF1468DD2F5C2C5DFD00 /* MarginAdjustable+Extensions.swift */; };
+ 6583C565BE5BB9E52213854AA85F5A93 /* warningIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = 6924A0A48B715EA35080ABB106B96BF7 /* warningIconSubtle.png */; };
+ 67DC4D170143131B8AFFB558FDD00465 /* SwiftMessages-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D091A06E439F734980F26F81E9161EF2 /* SwiftMessages-dummy.m */; };
+ 67F7D444EAC4475021B3458B21B2A162 /* Identifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88398B7A70E5B00495B670516D964701 /* Identifiable.swift */; };
+ 698F203577674AFA4BBCDE93B01B9EEC /* UIViewController+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57EB79F63EA99ADBBDA408015A4599BB /* UIViewController+Extensions.swift */; };
+ 6A04C3E1C3437ED6BC6F096302B458AB /* errorIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8605740B16E17342A29212D21C380249 /* errorIcon@2x.png */; };
+ 6CDE06668BB53C70BF1456F8EEE845D9 /* infoIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C40BBCF3A77C5C7A01708634BB4275C3 /* infoIconSubtle@3x.png */; };
+ 6DC0B420F622E197919276CFF2C063CE /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790409B3FBA491A9262ACCB929F30104 /* BaseView.swift */; };
+ 72026C4424B7A1650CBEED98ED9AA288 /* successIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B9CEE1B17C98E76723E7404C532515D /* successIconSubtle.png */; };
+ 744EA4AF597AFEFEE5B398434F47CA26 /* warningIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 71699C81494BC6585B862CDFC1CDAF54 /* warningIconLight@2x.png */; };
+ 7590FF543E2634A83059E509D5B05583 /* Pods-iMessageExtensionDemo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAB201AD00CAB811B045E2FFB5C03A8 /* Pods-iMessageExtensionDemo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 79BB175F4750822409AB9ED0A9D90D09 /* successIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6EA088414C10E47808EA8490D9BBF64F /* successIcon@3x.png */; };
+ 81B1015F29547CAB449757FC5ABCAFAB /* warningIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5FE01208AD70F1B35201AB04E50A23EC /* warningIconLight@3x.png */; };
+ 88D024879AEAE247899BFB50C8516515 /* Pods-iMessageDemo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D0ECE831FB5E0EE1D68E837671320C7 /* Pods-iMessageDemo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 8CB7CCDF07E1CE6838C7278BC19968B6 /* infoIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 79A086337846180B9A63D8492CCE45B4 /* infoIcon.png */; };
+ 8F63F1ABAB21FA99A6CB1A54D5F2B5AA /* infoIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 560722B244EB84DF745199247129C164 /* infoIcon@3x.png */; };
+ 942468E4C1AEFCF10D5043243B4007E7 /* NSBundle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 073CD58B2E8E255484D239A01D707B81 /* NSBundle+Extensions.swift */; };
+ 9FBBA6E4D3A2A4CA4BA8535E35D54CA8 /* successIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 44DAC25C8D6D72F70BD1CF9099BDAF10 /* successIconLight@2x.png */; };
+ A4724FC3B4F49DCBF50D395257BB6B8E /* CardView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 03B5D12D54ACC75F929389CFF15E91FF /* CardView.xib */; };
+ A52191D65F4C725EBF61D27F40FEA970 /* infoIconLight@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 88237113DAAD8ECF8D5E3FAA27D8A02F /* infoIconLight@3x.png */; };
+ A836F848C83565B2A0A06AB23D491946 /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9BBC4BF82FBB152E34F2D1EF36A0FB1 /* MessageView.swift */; };
+ A865FCE8718103C8E725EC1EC0F9F4F6 /* BackgroundViewable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86C1C9601BF8A5BC563062C310C0E3B5 /* BackgroundViewable.swift */; };
+ A8C4AD87F73E9C51F797F34BCFF5AA17 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAB6F611E86A4758835A715E4B4184F6 /* Foundation.framework */; };
+ A8EF6BE26B31A8713E37E0629F6466EB /* successIconLight.png in Resources */ = {isa = PBXBuildFile; fileRef = 252A5DF0FE3237691B8C50B969857389 /* successIconLight.png */; };
+ A90C06B459CC64A243DD1184024E5D22 /* infoIconSubtle.png in Resources */ = {isa = PBXBuildFile; fileRef = A6C7FF0D9E13571262231B72D0553E49 /* infoIconSubtle.png */; };
+ B04AA81A8A8CE0BCEFD5FAFD841F461F /* Task+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9610DCAAD9A55CDF73BAD54D523E1273 /* Task+Extensions.swift */; };
+ B1B4D240B65FFC5A7A981B9504C55270 /* NSLayoutConstraint+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 882EF814D0A1EE2AB28BFEE5C067EE6F /* NSLayoutConstraint+Extensions.swift */; };
+ B22AF07D79D1A82DE583AC49E3D472D3 /* Pods-iMessageExtensionDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F40CA14AD738DD186B4DA8FD14AE5BD /* Pods-iMessageExtensionDemo-dummy.m */; };
+ B61EBE61C31E78140BF12D32A008A43B /* StatusLine.xib in Resources */ = {isa = PBXBuildFile; fileRef = 62332870F1E2AE3FA16EE5ADC85C104A /* StatusLine.xib */; };
+ B646E1CD53F14E0DEE53740799C06AC5 /* SwiftMessages-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 080E269BABA7D072D8C51E29E9AC4A91 /* SwiftMessages-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ B6D0E2FA454A946D6C9A7494648F49D9 /* MessageGeometryProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28456F0421422D16D71D14D426309B3F /* MessageGeometryProxy.swift */; };
+ B9FDFA90A4FB68CA5357AB70427B4DCD /* TopBottomAnimationStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C61DD3C66AC7ADE1E9CCFE7A4A0BEA59 /* TopBottomAnimationStyle.swift */; };
+ BA4779B82B35B85EFE9F595624BA3943 /* UIEdgeInsets+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16B5B2B5429B01345E4DA361DE01904D /* UIEdgeInsets+Extensions.swift */; };
+ BAB66573FF29F6337237A8DA0EB9E3E8 /* PassthroughWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0398CE267904AF6C2FD03B3766511ECF /* PassthroughWindow.swift */; };
+ BBF31491EF3411DCFA7E649645229E2A /* successIconSubtle@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 47A710678B44C50DA470D1BCF94B87B8 /* successIconSubtle@3x.png */; };
+ C2031E7EC3C60B876F2AC04253D3AFC4 /* MessageViewConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06DB4311BFB347093FC18777A503B461 /* MessageViewConvertible.swift */; };
+ CCBFBDB03B2444C911BADDE6A6BA08AD /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9414B7316138752779A4B9C7E5C988DB /* Error.swift */; };
+ D3B31A631C754CAECABFA4DC672D3D0B /* warningIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 85C6BEF274CDB3807F9BD452A26C68E6 /* warningIconSubtle@2x.png */; };
+ D8DFC45149C57377B5C90B3457090564 /* warningIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = D47C1471CCFFBEF214DF9F0ECBDD408B /* warningIcon.png */; };
+ D9519DD580DF2E744AB4C4087FA28BCD /* Animator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F67BD26788FA0C70E942A7629E41C5E8 /* Animator.swift */; };
+ DC6C4E22FA8DD6FA491066A738132EF1 /* infoIconSubtle@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8026A87EEBF1A86A282563F974C4225C /* infoIconSubtle@2x.png */; };
+ DD406A0C002AC1D02A6E5794B1729C22 /* PassthroughView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03A865E97261799942A6F29092D3D7AE /* PassthroughView.swift */; };
+ DE2531A67AEBFED61A060DF13790C3BE /* errorIcon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 91013DDC05BDB2787740B0C9E5444D23 /* errorIcon@3x.png */; };
+ E03C930AD56F078DCD1357E5C83AD67A /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = B32459A84426DD5E88256AD61F3D4E91 /* Theme.swift */; };
+ E4906D67B9F27E11EE9F8E8F5C847A14 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D245E0514AAC1A2B9A6D5EA2F383E90F /* UIKit.framework */; };
+ E54040398A9AD751393A2171DC64D70E /* errorIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 71D489FBDD84B41576199298F717BC08 /* errorIcon.png */; };
+ EE9A5A3877D99BFCA5DA70BA4E049CA9 /* successIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DBF06E9B2F93F081139B8A6A922F569 /* successIcon@2x.png */; };
+ F2D3ABB0C7B6EB5B531E4E68C40AA89C /* PhysicsPanHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AEEED9FBEA6C5DB7EE3B95E7D8115B3 /* PhysicsPanHandler.swift */; };
+ F516490B5276943A352D597431B079B6 /* TopBottomAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F1B1264A726D334A72AB1CB001CA9F /* TopBottomAnimation.swift */; };
+ F667CC7C7F3285FC39427F2AAA8E7665 /* PhysicsAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D7E08E0434930866B59A3F17A3A577B /* PhysicsAnimation.swift */; };
+ F8D0D33FC1C833490057108C322E56CB /* MaskingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4854845AC1848C056C36719A5D7420 /* MaskingView.swift */; };
+ FC0E2BA3CD9C6C3ACF3681841D8EF5BA /* errorIconLight@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C49B964EF7710D818E0AF0321724EEF4 /* errorIconLight@2x.png */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
- 4B785BB517DA1D687C0B772C77660019 /* PBXContainerItemProxy */ = {
+ 146D3A65FCE17293CC3AD6CBEAE15F9A /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = DAB613A18652334F6BFC5F27BADF515D;
- remoteInfo = SwiftMessages;
+ remoteGlobalIDString = 1FC5E8328653C350899229BDF89FACE5;
+ remoteInfo = "SwiftMessages-SwiftMessages_SwiftMessages";
};
- D19F271ED5B0FED7305E55070B415EDB /* PBXContainerItemProxy */ = {
+ 70E6358901408AED062E820735630F69 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = 1FC5E8328653C350899229BDF89FACE5;
- remoteInfo = "SwiftMessages-SwiftMessages_SwiftMessages";
+ remoteGlobalIDString = DAB613A18652334F6BFC5F27BADF515D;
+ remoteInfo = SwiftMessages;
};
- DA9FA5DB745280F35DD4EFAC9A7A4FD7 /* PBXContainerItemProxy */ = {
+ D297C84AE0F13FB6A76F2F391D21D679 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
@@ -117,226 +125,242 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- 0038C9A582787F9882258E8D1080EACF /* warningIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIcon@3x.png"; path = "SwiftMessages/Resources/warningIcon@3x.png"; sourceTree = ""; };
- 007ACA6F89C6C856F78352A086F3B8EA /* CornerRoundingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CornerRoundingView.swift; path = SwiftMessages/CornerRoundingView.swift; sourceTree = ""; };
- 0201BC51C7CA061016B619400691A139 /* AccessibleMessage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AccessibleMessage.swift; path = SwiftMessages/AccessibleMessage.swift; sourceTree = ""; };
+ 004EE347886E2355CCB352F2AE7A35D6 /* warningIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIconLight.png; path = SwiftMessages/Resources/warningIconLight.png; sourceTree = ""; };
+ 0398CE267904AF6C2FD03B3766511ECF /* PassthroughWindow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughWindow.swift; path = SwiftMessages/PassthroughWindow.swift; sourceTree = ""; };
+ 03A865E97261799942A6F29092D3D7AE /* PassthroughView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughView.swift; path = SwiftMessages/PassthroughView.swift; sourceTree = ""; };
+ 03B5D12D54ACC75F929389CFF15E91FF /* CardView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = CardView.xib; path = SwiftMessages/Resources/CardView.xib; sourceTree = ""; };
+ 06DB4311BFB347093FC18777A503B461 /* MessageViewConvertible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageViewConvertible.swift; path = SwiftMessages/MessageViewConvertible.swift; sourceTree = ""; };
+ 073CD58B2E8E255484D239A01D707B81 /* NSBundle+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSBundle+Extensions.swift"; path = "SwiftMessages/NSBundle+Extensions.swift"; sourceTree = ""; };
+ 080E269BABA7D072D8C51E29E9AC4A91 /* SwiftMessages-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftMessages-umbrella.h"; sourceTree = ""; };
093D5BBE2A96A1A7AC0432A3AB933576 /* Pods-iMessageDemo-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-iMessageDemo-Info.plist"; sourceTree = ""; };
- 0AF65ECDAFAD03A79B5571C6F66D8F35 /* TopBottomAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TopBottomAnimation.swift; path = SwiftMessages/TopBottomAnimation.swift; sourceTree = ""; };
- 0BEC185781E869FB5FDB7F10538230C7 /* SwiftMessages.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftMessages.modulemap; sourceTree = ""; };
- 0D2B448BE319CF56A38E222C0B7DF4CB /* PhysicsAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PhysicsAnimation.swift; path = SwiftMessages/PhysicsAnimation.swift; sourceTree = ""; };
+ 0FD758C8718F3EEFB5E97E34A29CE1CC /* SwiftMessages-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftMessages-Info.plist"; sourceTree = ""; };
1341BB7116EC50FDF7062C6A91DEDF49 /* Pods-iMessageExtensionDemo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-iMessageExtensionDemo-acknowledgements.plist"; sourceTree = ""; };
- 141AADF8046C9D5EC8E194DF662BAC41 /* ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist"; sourceTree = ""; };
14BF989232A1D55A0FDAAB70B5A8E1BF /* Pods-iMessageDemo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-iMessageDemo-dummy.m"; sourceTree = ""; };
- 17ADABD24F805C5F7FF62167E7ABEF0A /* successIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconSubtle@3x.png"; path = "SwiftMessages/Resources/successIconSubtle@3x.png"; sourceTree = ""; };
- 1A331C2E0BE2AE2118D65AA1F12519F2 /* PassthroughWindow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PassthroughWindow.swift; path = SwiftMessages/PassthroughWindow.swift; sourceTree = ""; };
- 1E2FE4DB6869F330F19A3A5459AAFFFB /* StatusLine.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = StatusLine.xib; path = SwiftMessages/Resources/StatusLine.xib; sourceTree = ""; };
- 1ED635B9451869879B1A404F00C3CCC7 /* SwiftMessages-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftMessages-prefix.pch"; sourceTree = ""; };
- 24021DCE87BE9746D1DFB436C0A3AF7A /* Theme.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Theme.swift; path = SwiftMessages/Theme.swift; sourceTree = ""; };
- 29A39558830996C4F54686A1748B74B1 /* warningIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIcon@2x.png"; path = "SwiftMessages/Resources/warningIcon@2x.png"; sourceTree = ""; };
+ 14DF8F43552C4F1C4CAEFBAFD9A77004 /* MarginAdjustable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MarginAdjustable.swift; path = SwiftMessages/MarginAdjustable.swift; sourceTree = ""; };
+ 16B5B2B5429B01345E4DA361DE01904D /* UIEdgeInsets+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIEdgeInsets+Extensions.swift"; path = "SwiftMessages/UIEdgeInsets+Extensions.swift"; sourceTree = ""; };
+ 252A5DF0FE3237691B8C50B969857389 /* successIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIconLight.png; path = SwiftMessages/Resources/successIconLight.png; sourceTree = ""; };
+ 28456F0421422D16D71D14D426309B3F /* MessageGeometryProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageGeometryProxy.swift; path = SwiftMessages/MessageGeometryProxy.swift; sourceTree = ""; };
+ 2AB9866F195EB0AED31A33AEC27B67C1 /* WindowScene.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WindowScene.swift; path = SwiftMessages/WindowScene.swift; sourceTree = ""; };
+ 2CF5DC74916EBE02E70234620CD80150 /* infoIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIcon@2x.png"; path = "SwiftMessages/Resources/infoIcon@2x.png"; sourceTree = ""; };
2D0ECE831FB5E0EE1D68E837671320C7 /* Pods-iMessageDemo-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-iMessageDemo-umbrella.h"; sourceTree = ""; };
- 3259F99D03B6D738D7F47A625E7BD3BE /* warningIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIcon.png; path = SwiftMessages/Resources/warningIcon.png; sourceTree = ""; };
- 36F7B24601DF4C00B14EC8CE2D4A48DC /* UIEdgeInsets+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIEdgeInsets+Extensions.swift"; path = "SwiftMessages/UIEdgeInsets+Extensions.swift"; sourceTree = ""; };
- 3E2EB968B30DE56F38B5FCFFEDE9F88F /* NSBundle+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSBundle+Extensions.swift"; path = "SwiftMessages/NSBundle+Extensions.swift"; sourceTree = ""; };
- 45844D489A130BA91E91E7CDD4969862 /* infoIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconSubtle@2x.png"; path = "SwiftMessages/Resources/infoIconSubtle@2x.png"; sourceTree = ""; };
- 467EAD44C7F625F384822180F004E64F /* CALayer+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CALayer+Extensions.swift"; path = "SwiftMessages/CALayer+Extensions.swift"; sourceTree = ""; };
- 468D9889455DE51BD5BBC2360BDBB877 /* errorIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconSubtle@2x.png"; path = "SwiftMessages/Resources/errorIconSubtle@2x.png"; sourceTree = ""; };
- 4824F23D80FF9070A5F8A452DB11EB9A /* SwiftMessages.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftMessages.framework; path = SwiftMessages.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 48DC3BADDA3A20F2AEB8585117DAFA0D /* infoIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIcon@3x.png"; path = "SwiftMessages/Resources/infoIcon@3x.png"; sourceTree = ""; };
- 4D34E3F2A49E9024A96334DA4147F27B /* errorIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconLight@3x.png"; path = "SwiftMessages/Resources/errorIconLight@3x.png"; sourceTree = ""; };
- 52F1CA85E0EED7D94FE0036BC92EB3EC /* successIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIconLight.png; path = SwiftMessages/Resources/successIconLight.png; sourceTree = ""; };
- 59FEAC25BE3FCB9F8373DE26400CC89D /* SwiftMessages.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = SwiftMessages.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
- 5A16E25077F8D76288BE678E6AC1C884 /* SwiftMessages.Config+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SwiftMessages.Config+Extensions.swift"; path = "SwiftMessages/SwiftMessages.Config+Extensions.swift"; sourceTree = ""; };
+ 35F5FB13175EC0E13D53B445CE31395A /* CALayer+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CALayer+Extensions.swift"; path = "SwiftMessages/CALayer+Extensions.swift"; sourceTree = ""; };
+ 38D28C78FCAE6706F1294CEFA6B25F88 /* errorIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconSubtle@2x.png"; path = "SwiftMessages/Resources/errorIconSubtle@2x.png"; sourceTree = ""; };
+ 442F9FAEDF369CADB9E6E8FF3668FD95 /* Weak.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Weak.swift; path = SwiftMessages/Weak.swift; sourceTree = ""; };
+ 44DAC25C8D6D72F70BD1CF9099BDAF10 /* successIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconLight@2x.png"; path = "SwiftMessages/Resources/successIconLight@2x.png"; sourceTree = ""; };
+ 47A710678B44C50DA470D1BCF94B87B8 /* successIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconSubtle@3x.png"; path = "SwiftMessages/Resources/successIconSubtle@3x.png"; sourceTree = ""; };
+ 4824F23D80FF9070A5F8A452DB11EB9A /* SwiftMessages */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = SwiftMessages; path = SwiftMessages.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4DBF06E9B2F93F081139B8A6A922F569 /* successIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIcon@2x.png"; path = "SwiftMessages/Resources/successIcon@2x.png"; sourceTree = ""; };
+ 560722B244EB84DF745199247129C164 /* infoIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIcon@3x.png"; path = "SwiftMessages/Resources/infoIcon@3x.png"; sourceTree = ""; };
+ 5686DFC1E0B24A3051EF376AD8A162C0 /* successIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconLight@3x.png"; path = "SwiftMessages/Resources/successIconLight@3x.png"; sourceTree = ""; };
+ 573965F15F83BD70EEAC9E1E8B0F85C6 /* SwiftMessages.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = SwiftMessages.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
+ 57EB79F63EA99ADBBDA408015A4599BB /* UIViewController+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIViewController+Extensions.swift"; path = "SwiftMessages/UIViewController+Extensions.swift"; sourceTree = ""; };
5CAB201AD00CAB811B045E2FFB5C03A8 /* Pods-iMessageExtensionDemo-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-iMessageExtensionDemo-umbrella.h"; sourceTree = ""; };
+ 5E02B1554754BA1F8EF318D567875139 /* warningIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconSubtle@3x.png"; path = "SwiftMessages/Resources/warningIconSubtle@3x.png"; sourceTree = ""; };
+ 5F989D33CAC3BCDA9B3C4B18F23A4DBE /* MessageHostingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageHostingView.swift; path = SwiftMessages/MessageHostingView.swift; sourceTree = ""; };
+ 5FE01208AD70F1B35201AB04E50A23EC /* warningIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconLight@3x.png"; path = "SwiftMessages/Resources/warningIconLight@3x.png"; sourceTree = ""; };
+ 6228A8E37F7905D75917DD4CBE65B03C /* SwiftMessages.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SwiftMessages.modulemap; sourceTree = ""; };
+ 62332870F1E2AE3FA16EE5ADC85C104A /* StatusLine.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = StatusLine.xib; path = SwiftMessages/Resources/StatusLine.xib; sourceTree = ""; };
6489B2A759075E9DC1D1406734F45B5F /* Pods-iMessageExtensionDemo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-iMessageExtensionDemo.modulemap"; sourceTree = ""; };
- 676F359BE8561CF7512DB8B42CD7873A /* infoIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconLight@3x.png"; path = "SwiftMessages/Resources/infoIconLight@3x.png"; sourceTree = ""; };
- 705B5AF043D00B6538599B4EB1ECD77C /* CardView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = CardView.xib; path = SwiftMessages/Resources/CardView.xib; sourceTree = ""; };
- 7100245A2722BD53D5B3927ED649069F /* errorIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = errorIconLight.png; path = SwiftMessages/Resources/errorIconLight.png; sourceTree = ""; };
- 730840765E737D45772EBE66DB8A6D2E /* infoIconLight.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = infoIconLight.png; path = SwiftMessages/Resources/infoIconLight.png; sourceTree = ""; };
- 74C53DDA65E08AD7274EA6625408AB99 /* SwiftMessages-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "SwiftMessages-Info.plist"; sourceTree = ""; };
- 753B78926D6BB175E96AB6E6F3514E87 /* UIWindow+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIWindow+Extensions.swift"; path = "SwiftMessages/UIWindow+Extensions.swift"; sourceTree = ""; };
- 760BFB41B33B6ED91B3FFD68D39083A0 /* successIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIconLight@2x.png"; path = "SwiftMessages/Resources/successIconLight@2x.png"; sourceTree = ""; };
- 778F6E19CE49B8EDBAC2FCCD8195A55B /* MessageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MessageView.swift; path = SwiftMessages/MessageView.swift; sourceTree = ""; };
- 787EE6DA4FBC3BF85ED2CF0BB6EBF494 /* CenteredView.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = CenteredView.xib; path = SwiftMessages/Resources/CenteredView.xib; sourceTree = ""; };
- 79D34B3C6875DA0279CB934C84CD000B /* successIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIcon@2x.png"; path = "SwiftMessages/Resources/successIcon@2x.png"; sourceTree = ""; };
- 7C4DF53A4B44C246968618BF25962786 /* warningIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconLight@3x.png"; path = "SwiftMessages/Resources/warningIconLight@3x.png"; sourceTree = ""; };
- 7C8214A441D845A4A4DD6570FD5D458F /* MarginAdjustable+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "MarginAdjustable+Extensions.swift"; path = "SwiftMessages/MarginAdjustable+Extensions.swift"; sourceTree = ""; };
+ 6924A0A48B715EA35080ABB106B96BF7 /* warningIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIconSubtle.png; path = SwiftMessages/Resources/warningIconSubtle.png; sourceTree = ""; };
+ 6C12E87D0EA045A56FC0B45F072C74D2 /* errorIconSubtle@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIconSubtle@3x.png"; path = "SwiftMessages/Resources/errorIconSubtle@3x.png"; sourceTree = ""; };
+ 6EA088414C10E47808EA8490D9BBF64F /* successIcon@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "successIcon@3x.png"; path = "SwiftMessages/Resources/successIcon@3x.png"; sourceTree = ""; };
+ 71699C81494BC6585B862CDFC1CDAF54 /* warningIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconLight@2x.png"; path = "SwiftMessages/Resources/warningIconLight@2x.png"; sourceTree = ""; };
+ 71D489FBDD84B41576199298F717BC08 /* errorIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = errorIcon.png; path = SwiftMessages/Resources/errorIcon.png; sourceTree = ""; };
+ 74793ADC8ADF7674EA6C3041E2B54354 /* successIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIcon.png; path = SwiftMessages/Resources/successIcon.png; sourceTree = ""; };
+ 790409B3FBA491A9262ACCB929F30104 /* BaseView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseView.swift; path = SwiftMessages/BaseView.swift; sourceTree = ""; };
+ 79A086337846180B9A63D8492CCE45B4 /* infoIcon.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = infoIcon.png; path = SwiftMessages/Resources/infoIcon.png; sourceTree = ""; };
+ 7B9CEE1B17C98E76723E7404C532515D /* successIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = successIconSubtle.png; path = SwiftMessages/Resources/successIconSubtle.png; sourceTree = ""; };
7CC6A596A9C1659D8E93222DA4144414 /* Pods-iMessageExtensionDemo-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-iMessageExtensionDemo-Info.plist"; sourceTree = ""; };
7F40CA14AD738DD186B4DA8FD14AE5BD /* Pods-iMessageExtensionDemo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-iMessageExtensionDemo-dummy.m"; sourceTree = ""; };
+ 8026A87EEBF1A86A282563F974C4225C /* infoIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconSubtle@2x.png"; path = "SwiftMessages/Resources/infoIconSubtle@2x.png"; sourceTree = ""; };
820B743874F7AC9F9E3970D68E2E60FA /* Pods-iMessageDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-iMessageDemo.release.xcconfig"; sourceTree = ""; };
- 8315EA451FE61625920FEF68174A0D22 /* infoIconLight@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconLight@2x.png"; path = "SwiftMessages/Resources/infoIconLight@2x.png"; sourceTree = ""; };
- 860D833A7A1B108A89ED34AD74778AC0 /* warningIconSubtle.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = warningIconSubtle.png; path = SwiftMessages/Resources/warningIconSubtle.png; sourceTree = ""; };
- 87745BF2C7154EF88509BED0D71243F1 /* SwiftMessages.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftMessages.debug.xcconfig; sourceTree = ""; };
- 88D73E42D996B226222A4EBA46F7DC6D /* Weak.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Weak.swift; path = SwiftMessages/Weak.swift; sourceTree = ""; };
- 8AD355ED684A939F2A4E333F95E8AC31 /* warningIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconSubtle@2x.png"; path = "SwiftMessages/Resources/warningIconSubtle@2x.png"; sourceTree = ""; };
- 8D219D80184B8ED97808EE17507B213A /* Animator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Animator.swift; path = SwiftMessages/Animator.swift; sourceTree = ""; };
+ 85C6BEF274CDB3807F9BD452A26C68E6 /* warningIconSubtle@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "warningIconSubtle@2x.png"; path = "SwiftMessages/Resources/warningIconSubtle@2x.png"; sourceTree = ""; };
+ 8605740B16E17342A29212D21C380249 /* errorIcon@2x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "errorIcon@2x.png"; path = "SwiftMessages/Resources/errorIcon@2x.png"; sourceTree = ""; };
+ 86872F4639B26435D20BED0CE7E35C7F /* CornerRoundingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CornerRoundingView.swift; path = SwiftMessages/CornerRoundingView.swift; sourceTree = ""; };
+ 86C1C9601BF8A5BC563062C310C0E3B5 /* BackgroundViewable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BackgroundViewable.swift; path = SwiftMessages/BackgroundViewable.swift; sourceTree = ""; };
+ 88237113DAAD8ECF8D5E3FAA27D8A02F /* infoIconLight@3x.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; name = "infoIconLight@3x.png"; path = "SwiftMessages/Resources/infoIconLight@3x.png"; sourceTree = ""; };
+ 882EF814D0A1EE2AB28BFEE5C067EE6F /* NSLayoutConstraint+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSLayoutConstraint+Extensions.swift"; path = "SwiftMessages/NSLayoutConstraint+Extensions.swift"; sourceTree = ""; };
+ 88398B7A70E5B00495B670516D964701 /* Identifiable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Identifiable.swift; path = SwiftMessages/Identifiable.swift; sourceTree = ""; };
+ 8940290DCDAD08810FE0CD944F376444 /* ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-SwiftMessages_SwiftMessages-SwiftMessages-Info.plist"; sourceTree = ""; };
+ 8AEEED9FBEA6C5DB7EE3B95E7D8115B3 /* PhysicsPanHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PhysicsPanHandler.swift; path = SwiftMessages/PhysicsPanHandler.swift; sourceTree = ""; };
+ 8D18688EA04EA2F2BC48ED05D1FE5404 /* Presenter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Presenter.swift; path = SwiftMessages/Presenter.swift; sourceTree = "