├── .gitignore
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── Example
└── SwiftMessageBarExample
│ ├── SwiftMessageBarExample.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── SwiftMessageBarExample
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
│ ├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ └── ViewController.swift
├── LICENSE
├── Package.swift
├── README.md
├── SwiftMessageBar.podspec
├── SwiftMessageBar.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ └── SwiftMessageBar.xcscheme
├── SwiftMessageBar.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── SwiftMessageBar
├── Info.plist
├── Message.swift
├── MessageType.swift
├── Queue.swift
├── Resources
│ ├── icon-error.png
│ ├── icon-error@2x.png
│ ├── icon-error@3x.png
│ ├── icon-info.png
│ ├── icon-info@2x.png
│ ├── icon-info@3x.png
│ ├── icon-success@1x.png
│ ├── icon-success@2x.png
│ └── icon-success@3x.png
├── SwiftMessageBar.h
└── SwiftMessageBar.swift
└── SwiftMessageBarTests
├── Info.plist
└── QueueTests.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | ### https://raw.github.com/github/gitignore/c70e357bfde8a842faca6574f1dfc6ad416dfc2a/Global/Xcode.gitignore
2 |
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.xcuserstate
17 |
18 |
19 | ### https://raw.github.com/github/gitignore/c70e357bfde8a842faca6574f1dfc6ad416dfc2a/Global/JetBrains.gitignore
20 |
21 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
22 |
23 | ## Directory-based project format
24 | .idea/
25 | # if you remove the above rule, at least ignore user-specific stuff:
26 | # .idea/workspace.xml
27 | # .idea/tasks.xml
28 | # and these sensitive or high-churn files:
29 | # .idea/dataSources.ids
30 | # .idea/dataSources.xml
31 | # .idea/sqlDataSources.xml
32 | # .idea/dynamic.xml
33 |
34 | ## File-based project format
35 | *.ipr
36 | *.iml
37 | *.iws
38 |
39 | ## Additional for IntelliJ
40 | out/
41 |
42 | # generated by mpeltonen/sbt-idea plugin
43 | .idea_modules/
44 |
45 | # generated by JIRA plugin
46 | atlassian-ide-plugin.xml
47 |
48 | # generated by Crashlytics plugin (for Android Studio and Intellij)
49 | com_crashlytics_export_strings.xml
50 |
51 |
52 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/SwiftMessageBarExample/SwiftMessageBarExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | F2AB590F1B28B3B3001DCC74 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2AB590E1B28B3B3001DCC74 /* AppDelegate.swift */; };
11 | F2AB59111B28B3B3001DCC74 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2AB59101B28B3B3001DCC74 /* ViewController.swift */; };
12 | F2AB59141B28B3B3001DCC74 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F2AB59121B28B3B3001DCC74 /* Main.storyboard */; };
13 | F2AB59161B28B3B3001DCC74 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F2AB59151B28B3B3001DCC74 /* Images.xcassets */; };
14 | F2AB59191B28B3B3001DCC74 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = F2AB59171B28B3B3001DCC74 /* LaunchScreen.xib */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXContainerItemProxy section */
18 | F2AB59331B28B3C9001DCC74 /* PBXContainerItemProxy */ = {
19 | isa = PBXContainerItemProxy;
20 | containerPortal = F2AB592E1B28B3C9001DCC74 /* SwiftMessageBar.xcodeproj */;
21 | proxyType = 2;
22 | remoteGlobalIDString = F2AB58E21B28B33C001DCC74;
23 | remoteInfo = SwiftMessageBar;
24 | };
25 | F2AB59371B28B3D1001DCC74 /* PBXContainerItemProxy */ = {
26 | isa = PBXContainerItemProxy;
27 | containerPortal = F2AB592E1B28B3C9001DCC74 /* SwiftMessageBar.xcodeproj */;
28 | proxyType = 1;
29 | remoteGlobalIDString = F2AB58E11B28B33C001DCC74;
30 | remoteInfo = SwiftMessageBar;
31 | };
32 | /* End PBXContainerItemProxy section */
33 |
34 | /* Begin PBXFileReference section */
35 | F2AB59091B28B3B3001DCC74 /* SwiftMessageBarExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftMessageBarExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
36 | F2AB590D1B28B3B3001DCC74 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | F2AB590E1B28B3B3001DCC74 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
38 | F2AB59101B28B3B3001DCC74 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
39 | F2AB59131B28B3B3001DCC74 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
40 | F2AB59151B28B3B3001DCC74 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
41 | F2AB59181B28B3B3001DCC74 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
42 | F2AB592E1B28B3C9001DCC74 /* SwiftMessageBar.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SwiftMessageBar.xcodeproj; path = ../../SwiftMessageBar.xcodeproj; sourceTree = ""; };
43 | /* End PBXFileReference section */
44 |
45 | /* Begin PBXFrameworksBuildPhase section */
46 | F2AB59061B28B3B3001DCC74 /* Frameworks */ = {
47 | isa = PBXFrameworksBuildPhase;
48 | buildActionMask = 2147483647;
49 | files = (
50 | );
51 | runOnlyForDeploymentPostprocessing = 0;
52 | };
53 | /* End PBXFrameworksBuildPhase section */
54 |
55 | /* Begin PBXGroup section */
56 | F2AB59001B28B3B3001DCC74 = {
57 | isa = PBXGroup;
58 | children = (
59 | F2AB592E1B28B3C9001DCC74 /* SwiftMessageBar.xcodeproj */,
60 | F2AB590B1B28B3B3001DCC74 /* SwiftMessageBarExample */,
61 | F2AB590A1B28B3B3001DCC74 /* Products */,
62 | );
63 | indentWidth = 2;
64 | sourceTree = "";
65 | tabWidth = 2;
66 | };
67 | F2AB590A1B28B3B3001DCC74 /* Products */ = {
68 | isa = PBXGroup;
69 | children = (
70 | F2AB59091B28B3B3001DCC74 /* SwiftMessageBarExample.app */,
71 | );
72 | name = Products;
73 | sourceTree = "";
74 | };
75 | F2AB590B1B28B3B3001DCC74 /* SwiftMessageBarExample */ = {
76 | isa = PBXGroup;
77 | children = (
78 | F2AB590E1B28B3B3001DCC74 /* AppDelegate.swift */,
79 | F2AB59101B28B3B3001DCC74 /* ViewController.swift */,
80 | F2AB59121B28B3B3001DCC74 /* Main.storyboard */,
81 | F2AB59151B28B3B3001DCC74 /* Images.xcassets */,
82 | F2AB59171B28B3B3001DCC74 /* LaunchScreen.xib */,
83 | F2AB590C1B28B3B3001DCC74 /* Supporting Files */,
84 | );
85 | path = SwiftMessageBarExample;
86 | sourceTree = "";
87 | };
88 | F2AB590C1B28B3B3001DCC74 /* Supporting Files */ = {
89 | isa = PBXGroup;
90 | children = (
91 | F2AB590D1B28B3B3001DCC74 /* Info.plist */,
92 | );
93 | name = "Supporting Files";
94 | sourceTree = "";
95 | };
96 | F2AB592F1B28B3C9001DCC74 /* Products */ = {
97 | isa = PBXGroup;
98 | children = (
99 | F2AB59341B28B3C9001DCC74 /* SwiftMessageBar.framework */,
100 | );
101 | name = Products;
102 | sourceTree = "";
103 | };
104 | /* End PBXGroup section */
105 |
106 | /* Begin PBXNativeTarget section */
107 | F2AB59081B28B3B3001DCC74 /* SwiftMessageBarExample */ = {
108 | isa = PBXNativeTarget;
109 | buildConfigurationList = F2AB59281B28B3B3001DCC74 /* Build configuration list for PBXNativeTarget "SwiftMessageBarExample" */;
110 | buildPhases = (
111 | F2AB59051B28B3B3001DCC74 /* Sources */,
112 | F2AB59061B28B3B3001DCC74 /* Frameworks */,
113 | F2AB59071B28B3B3001DCC74 /* Resources */,
114 | );
115 | buildRules = (
116 | );
117 | dependencies = (
118 | F2AB59381B28B3D1001DCC74 /* PBXTargetDependency */,
119 | );
120 | name = SwiftMessageBarExample;
121 | productName = SwiftMessageBarExample;
122 | productReference = F2AB59091B28B3B3001DCC74 /* SwiftMessageBarExample.app */;
123 | productType = "com.apple.product-type.application";
124 | };
125 | /* End PBXNativeTarget section */
126 |
127 | /* Begin PBXProject section */
128 | F2AB59011B28B3B3001DCC74 /* Project object */ = {
129 | isa = PBXProject;
130 | attributes = {
131 | LastSwiftUpdateCheck = 0700;
132 | LastUpgradeCheck = 1200;
133 | ORGANIZATIONNAME = Schnaub;
134 | TargetAttributes = {
135 | F2AB59081B28B3B3001DCC74 = {
136 | CreatedOnToolsVersion = 6.3.2;
137 | LastSwiftMigration = 1020;
138 | };
139 | };
140 | };
141 | buildConfigurationList = F2AB59041B28B3B3001DCC74 /* Build configuration list for PBXProject "SwiftMessageBarExample" */;
142 | compatibilityVersion = "Xcode 3.2";
143 | developmentRegion = en;
144 | hasScannedForEncodings = 0;
145 | knownRegions = (
146 | en,
147 | Base,
148 | );
149 | mainGroup = F2AB59001B28B3B3001DCC74;
150 | productRefGroup = F2AB590A1B28B3B3001DCC74 /* Products */;
151 | projectDirPath = "";
152 | projectReferences = (
153 | {
154 | ProductGroup = F2AB592F1B28B3C9001DCC74 /* Products */;
155 | ProjectRef = F2AB592E1B28B3C9001DCC74 /* SwiftMessageBar.xcodeproj */;
156 | },
157 | );
158 | projectRoot = "";
159 | targets = (
160 | F2AB59081B28B3B3001DCC74 /* SwiftMessageBarExample */,
161 | );
162 | };
163 | /* End PBXProject section */
164 |
165 | /* Begin PBXReferenceProxy section */
166 | F2AB59341B28B3C9001DCC74 /* SwiftMessageBar.framework */ = {
167 | isa = PBXReferenceProxy;
168 | fileType = wrapper.framework;
169 | path = SwiftMessageBar.framework;
170 | remoteRef = F2AB59331B28B3C9001DCC74 /* PBXContainerItemProxy */;
171 | sourceTree = BUILT_PRODUCTS_DIR;
172 | };
173 | /* End PBXReferenceProxy section */
174 |
175 | /* Begin PBXResourcesBuildPhase section */
176 | F2AB59071B28B3B3001DCC74 /* Resources */ = {
177 | isa = PBXResourcesBuildPhase;
178 | buildActionMask = 2147483647;
179 | files = (
180 | F2AB59141B28B3B3001DCC74 /* Main.storyboard in Resources */,
181 | F2AB59191B28B3B3001DCC74 /* LaunchScreen.xib in Resources */,
182 | F2AB59161B28B3B3001DCC74 /* Images.xcassets in Resources */,
183 | );
184 | runOnlyForDeploymentPostprocessing = 0;
185 | };
186 | /* End PBXResourcesBuildPhase section */
187 |
188 | /* Begin PBXSourcesBuildPhase section */
189 | F2AB59051B28B3B3001DCC74 /* Sources */ = {
190 | isa = PBXSourcesBuildPhase;
191 | buildActionMask = 2147483647;
192 | files = (
193 | F2AB59111B28B3B3001DCC74 /* ViewController.swift in Sources */,
194 | F2AB590F1B28B3B3001DCC74 /* AppDelegate.swift in Sources */,
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXSourcesBuildPhase section */
199 |
200 | /* Begin PBXTargetDependency section */
201 | F2AB59381B28B3D1001DCC74 /* PBXTargetDependency */ = {
202 | isa = PBXTargetDependency;
203 | name = SwiftMessageBar;
204 | targetProxy = F2AB59371B28B3D1001DCC74 /* PBXContainerItemProxy */;
205 | };
206 | /* End PBXTargetDependency section */
207 |
208 | /* Begin PBXVariantGroup section */
209 | F2AB59121B28B3B3001DCC74 /* Main.storyboard */ = {
210 | isa = PBXVariantGroup;
211 | children = (
212 | F2AB59131B28B3B3001DCC74 /* Base */,
213 | );
214 | name = Main.storyboard;
215 | sourceTree = "";
216 | };
217 | F2AB59171B28B3B3001DCC74 /* LaunchScreen.xib */ = {
218 | isa = PBXVariantGroup;
219 | children = (
220 | F2AB59181B28B3B3001DCC74 /* Base */,
221 | );
222 | name = LaunchScreen.xib;
223 | sourceTree = "";
224 | };
225 | /* End PBXVariantGroup section */
226 |
227 | /* Begin XCBuildConfiguration section */
228 | F2AB59261B28B3B3001DCC74 /* Debug */ = {
229 | isa = XCBuildConfiguration;
230 | buildSettings = {
231 | ALWAYS_SEARCH_USER_PATHS = NO;
232 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
233 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
234 | CLANG_CXX_LIBRARY = "libc++";
235 | CLANG_ENABLE_MODULES = YES;
236 | CLANG_ENABLE_OBJC_ARC = YES;
237 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
238 | CLANG_WARN_BOOL_CONVERSION = YES;
239 | CLANG_WARN_COMMA = YES;
240 | CLANG_WARN_CONSTANT_CONVERSION = YES;
241 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
242 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
243 | CLANG_WARN_EMPTY_BODY = YES;
244 | CLANG_WARN_ENUM_CONVERSION = YES;
245 | CLANG_WARN_INFINITE_RECURSION = YES;
246 | CLANG_WARN_INT_CONVERSION = YES;
247 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
248 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
249 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
250 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
251 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
252 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
253 | CLANG_WARN_STRICT_PROTOTYPES = YES;
254 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
255 | CLANG_WARN_UNREACHABLE_CODE = YES;
256 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
257 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
258 | COPY_PHASE_STRIP = NO;
259 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
260 | ENABLE_STRICT_OBJC_MSGSEND = YES;
261 | ENABLE_TESTABILITY = YES;
262 | GCC_C_LANGUAGE_STANDARD = gnu99;
263 | GCC_DYNAMIC_NO_PIC = NO;
264 | GCC_NO_COMMON_BLOCKS = YES;
265 | GCC_OPTIMIZATION_LEVEL = 0;
266 | GCC_PREPROCESSOR_DEFINITIONS = (
267 | "DEBUG=1",
268 | "$(inherited)",
269 | );
270 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
271 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
272 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
273 | GCC_WARN_UNDECLARED_SELECTOR = YES;
274 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
275 | GCC_WARN_UNUSED_FUNCTION = YES;
276 | GCC_WARN_UNUSED_VARIABLE = YES;
277 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
278 | MTL_ENABLE_DEBUG_INFO = YES;
279 | ONLY_ACTIVE_ARCH = YES;
280 | SDKROOT = iphoneos;
281 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
282 | SWIFT_VERSION = 4.0;
283 | };
284 | name = Debug;
285 | };
286 | F2AB59271B28B3B3001DCC74 /* Release */ = {
287 | isa = XCBuildConfiguration;
288 | buildSettings = {
289 | ALWAYS_SEARCH_USER_PATHS = NO;
290 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
291 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
292 | CLANG_CXX_LIBRARY = "libc++";
293 | CLANG_ENABLE_MODULES = YES;
294 | CLANG_ENABLE_OBJC_ARC = YES;
295 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
296 | CLANG_WARN_BOOL_CONVERSION = YES;
297 | CLANG_WARN_COMMA = YES;
298 | CLANG_WARN_CONSTANT_CONVERSION = YES;
299 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
300 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
301 | CLANG_WARN_EMPTY_BODY = YES;
302 | CLANG_WARN_ENUM_CONVERSION = YES;
303 | CLANG_WARN_INFINITE_RECURSION = YES;
304 | CLANG_WARN_INT_CONVERSION = YES;
305 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
306 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
307 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
308 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
309 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
310 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
311 | CLANG_WARN_STRICT_PROTOTYPES = YES;
312 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
313 | CLANG_WARN_UNREACHABLE_CODE = YES;
314 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
315 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
316 | COPY_PHASE_STRIP = NO;
317 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
318 | ENABLE_NS_ASSERTIONS = NO;
319 | ENABLE_STRICT_OBJC_MSGSEND = YES;
320 | GCC_C_LANGUAGE_STANDARD = gnu99;
321 | GCC_NO_COMMON_BLOCKS = YES;
322 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
323 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
324 | GCC_WARN_UNDECLARED_SELECTOR = YES;
325 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
326 | GCC_WARN_UNUSED_FUNCTION = YES;
327 | GCC_WARN_UNUSED_VARIABLE = YES;
328 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
329 | MTL_ENABLE_DEBUG_INFO = NO;
330 | SDKROOT = iphoneos;
331 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
332 | SWIFT_VERSION = 4.0;
333 | VALIDATE_PRODUCT = YES;
334 | };
335 | name = Release;
336 | };
337 | F2AB59291B28B3B3001DCC74 /* Debug */ = {
338 | isa = XCBuildConfiguration;
339 | buildSettings = {
340 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
341 | INFOPLIST_FILE = SwiftMessageBarExample/Info.plist;
342 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
343 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
344 | PRODUCT_BUNDLE_IDENTIFIER = "com.schnaub.$(PRODUCT_NAME:rfc1034identifier)";
345 | PRODUCT_NAME = "$(TARGET_NAME)";
346 | SWIFT_VERSION = 5.0;
347 | };
348 | name = Debug;
349 | };
350 | F2AB592A1B28B3B3001DCC74 /* Release */ = {
351 | isa = XCBuildConfiguration;
352 | buildSettings = {
353 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
354 | INFOPLIST_FILE = SwiftMessageBarExample/Info.plist;
355 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
356 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
357 | PRODUCT_BUNDLE_IDENTIFIER = "com.schnaub.$(PRODUCT_NAME:rfc1034identifier)";
358 | PRODUCT_NAME = "$(TARGET_NAME)";
359 | SWIFT_VERSION = 5.0;
360 | };
361 | name = Release;
362 | };
363 | /* End XCBuildConfiguration section */
364 |
365 | /* Begin XCConfigurationList section */
366 | F2AB59041B28B3B3001DCC74 /* Build configuration list for PBXProject "SwiftMessageBarExample" */ = {
367 | isa = XCConfigurationList;
368 | buildConfigurations = (
369 | F2AB59261B28B3B3001DCC74 /* Debug */,
370 | F2AB59271B28B3B3001DCC74 /* Release */,
371 | );
372 | defaultConfigurationIsVisible = 0;
373 | defaultConfigurationName = Release;
374 | };
375 | F2AB59281B28B3B3001DCC74 /* Build configuration list for PBXNativeTarget "SwiftMessageBarExample" */ = {
376 | isa = XCConfigurationList;
377 | buildConfigurations = (
378 | F2AB59291B28B3B3001DCC74 /* Debug */,
379 | F2AB592A1B28B3B3001DCC74 /* Release */,
380 | );
381 | defaultConfigurationIsVisible = 0;
382 | defaultConfigurationName = Release;
383 | };
384 | /* End XCConfigurationList section */
385 | };
386 | rootObject = F2AB59011B28B3B3001DCC74 /* Project object */;
387 | }
388 |
--------------------------------------------------------------------------------
/Example/SwiftMessageBarExample/SwiftMessageBarExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/SwiftMessageBarExample/SwiftMessageBarExample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Schnaub. All rights reserved.
3 | //
4 |
5 | import UIKit
6 |
7 | @main
8 | class AppDelegate: UIResponder, UIApplicationDelegate {
9 |
10 | var window: UIWindow?
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/Example/SwiftMessageBarExample/SwiftMessageBarExample/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Example/SwiftMessageBarExample/SwiftMessageBarExample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
33 |
40 |
49 |
58 |
68 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Example/SwiftMessageBarExample/SwiftMessageBarExample/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/Example/SwiftMessageBarExample/SwiftMessageBarExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Example/SwiftMessageBarExample/SwiftMessageBarExample/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Schnaub. All rights reserved.
3 | //
4 |
5 | import UIKit
6 | import SwiftMessageBar
7 |
8 | final class ViewController: UIViewController {
9 |
10 | private var uuid: UUID?
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | let messageBarConfig = SwiftMessageBar.Config(successColor: .orange, isStatusBarHidden: true)
15 | SwiftMessageBar.setSharedConfig(messageBarConfig)
16 | }
17 |
18 | @IBAction private func showSuccess() {
19 | let message = "A really long message can go here, to provide a description for the user"
20 | uuid = SwiftMessageBar.showMessage(
21 | withTitle: nil,
22 | message: message,
23 | type: .success,
24 | duration: 3,
25 | dismiss: false
26 | ) {
27 | print("Dismiss callback")
28 | }
29 | }
30 |
31 | @IBAction private func showError() {
32 | let message = "A really long message can go here, to provide a description for the user"
33 | uuid = SwiftMessageBar.showMessage(
34 | withTitle: "Error",
35 | message: message,
36 | type: .error,
37 | duration: 3
38 | ) {
39 | print("Dismiss callback")
40 | }
41 | }
42 |
43 | @IBAction private func showInfo() {
44 | let message = "A really long message can go here, to provide a description for the user"
45 | uuid = SwiftMessageBar.showMessage(withTitle: "Info", message: message, type: .info, duration: 3) {
46 | print("Dismiss callback")
47 | }
48 | }
49 |
50 | @IBAction private func clearAll() {
51 | SwiftMessageBar.sharedMessageBar.cancelAll(force: true)
52 | uuid = nil
53 | }
54 |
55 | @IBAction private func clearCurrent() {
56 | if let id = uuid {
57 | SwiftMessageBar.sharedMessageBar.cancel(withId: id)
58 | uuid = nil
59 | }
60 | }
61 |
62 | @IBAction private func showSuccessWithAccesoryView() {
63 | let message = "A really long message can go here, to provide a description for the user"
64 | let button = UIButton(type: .roundedRect, primaryAction: UIAction { _ in
65 | print("Button tapped")
66 | })
67 | button.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
68 | button.setContentHuggingPriority(.required, for: .horizontal)
69 | button.setTitle("Open", for: .normal)
70 | button.tintColor = .orange
71 | button.backgroundColor = .white
72 | button.layer.cornerRadius = 6
73 |
74 | uuid = SwiftMessageBar.showMessage(
75 | withTitle: nil,
76 | message: message,
77 | type: .success,
78 | duration: 3,
79 | dismiss: false,
80 | accessoryView: button
81 | ) {
82 | print("Dismiss callback")
83 | }
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Jan Gorman
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version: 5.9
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "SwiftMessageBar",
7 | platforms: [
8 | .iOS(.v12),
9 | ],
10 | products: [
11 | .library(
12 | name: "SwiftMessageBar",
13 | targets: ["SwiftMessageBar"]
14 | ),
15 | ],
16 | targets: [
17 | .target(
18 | name: "SwiftMessageBar",
19 | path: "SwiftMessageBar",
20 | resources: [
21 | .process("Resources")
22 | ]
23 | ),
24 | .testTarget(
25 | name: "SwiftMessageBarTests",
26 | dependencies: ["SwiftMessageBar"],
27 | path: "SwiftMessageBarTests"
28 | ),
29 | ]
30 | )
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/Carthage/Carthage)
2 | [](http://cocoapods.org/pods/SwiftMessageBar)
3 | [](http://cocoapods.org/pods/SwiftMessageBar)
4 | [](http://cocoapods.org/pods/SwiftMessageBar)
5 |
6 | # SwiftMessageBar
7 |
8 | An iOS message bar, written in Swift
9 |
10 | 
11 |
12 | ## Requirements
13 |
14 | - iOS 9.0+
15 | - Swift 5
16 | - Xcode 10.2+
17 |
18 | ## Installation
19 |
20 | You can use [Carthage](https://github.com/Carthage/Carthage):
21 |
22 | ```ogdl
23 | github "JanGorman/SwiftMessageBar"
24 | ```
25 |
26 | or [CocoaPods](http://cocoapods.org):
27 |
28 | ```ruby
29 | pod 'SwiftMessageBar'
30 | ```
31 |
32 | ## Usage
33 |
34 | The included sample code shows how to use the message bar. There are three different message types:
35 |
36 | ```swift
37 | enum MessageType {
38 | case error, success, info
39 | }
40 | ```
41 |
42 | To display a message:
43 |
44 | ```swift
45 | import SwiftMessageBar
46 |
47 | @IBAction func showSuccess(sender: AnyObject) {
48 | SwiftMessageBar.showMessage(withTitle: "Success", message: "The Message Body", type: .success)
49 | }
50 | ```
51 |
52 | You can customize the duration of each message and also pass in a tap handler closure that is executed when a user taps on the message.
53 |
54 | To customize the look of the messages, create a custom `Config` and set it on the shared messagebar. You can adjust colors, fonts as well as custom images. `Config` comes with a Builder class for easy configuration. For example:
55 |
56 | ```swift
57 | let config = SwiftMessageBar.Config.Builder()
58 | .withErrorColor(.green)
59 | .withSuccessColor(.red)
60 | .withTitleFont(.boldSystemFont(ofSize: 30))
61 | .withMessageFont(.systemFont(ofSize: 17))
62 | .build()
63 | SwiftMessageBar.setSharedConfig(config)
64 | ```
65 |
66 | ### Haptic Feedback
67 |
68 | Per default SwiftMessageBar provides the user with haptic feedback using [UINotificationFeedbackGenerator](https://developer.apple.com/documentation/uikit/uinotificationfeedbackgenerator). You can opt out of this behaviour by disabling it in the configuration:
69 |
70 | ```swift
71 | let config = SwiftMessageBar.Config.Builder()
72 | .withHapticFeedbackEnabled(false)
73 | .build()
74 | SwiftMessageBar.setSharedConfig(config)
75 | ```
76 |
77 | ## Licence
78 |
79 | SwiftMessageBar is released under the MIT license. See LICENSE for details
80 |
--------------------------------------------------------------------------------
/SwiftMessageBar.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = 'SwiftMessageBar'
4 | s.version = '5.6.2'
5 | s.summary = 'A Swift Message Bar'
6 | s.swift_version = '5.0'
7 |
8 | s.description = <<-DESC
9 | A longer description of SwiftMessageBar in Markdown format.
10 |
11 | * Think: Why did you write this? What is the focus? What does it do?
12 | * CocoaPods will be using this to generate tags, and improve search results.
13 | * Try to keep it short, snappy and to the point.
14 | * Finally, don't worry about the indent, CocoaPods strips it!
15 | DESC
16 |
17 | s.homepage = 'https://github.com/JanGorman/SwiftMessageBar'
18 | s.license = 'MIT'
19 | s.authors = { 'Jan Gorman' => 'https://github.com/JanGorman/', 'Ramy Kfoury' => 'https://github.com/ramy-kfoury/' }
20 | s.social_media_url = 'http://twitter.com/JanGorman'
21 |
22 | s.platform = :ios, '12.0'
23 |
24 | s.source = { :git => 'https://github.com/JanGorman/SwiftMessageBar.git', :tag => s.version }
25 |
26 | s.source_files = 'SwiftMessageBar/*.swift'
27 | s.resources = 'SwiftMessageBar/*.png'
28 |
29 | end
30 |
--------------------------------------------------------------------------------
/SwiftMessageBar.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 77BBDF7E209705E600BDED60 /* DeviceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77BBDF7D209705E600BDED60 /* DeviceType.swift */; };
11 | 77E9E14E205167C100E157F5 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77E9E14D205167C100E157F5 /* Queue.swift */; };
12 | 77EBFCB420519D5000AFE1F9 /* MessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77EBFCB320519D5000AFE1F9 /* MessageType.swift */; };
13 | B5501F142AF22912009AE3D3 /* icon-info@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F0B2AF22912009AE3D3 /* icon-info@3x.png */; };
14 | B5501F152AF22912009AE3D3 /* icon-success@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F0C2AF22912009AE3D3 /* icon-success@1x.png */; };
15 | B5501F162AF22912009AE3D3 /* icon-info@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F0D2AF22912009AE3D3 /* icon-info@2x.png */; };
16 | B5501F172AF22912009AE3D3 /* icon-error.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F0E2AF22912009AE3D3 /* icon-error.png */; };
17 | B5501F182AF22912009AE3D3 /* icon-info.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F0F2AF22912009AE3D3 /* icon-info.png */; };
18 | B5501F192AF22912009AE3D3 /* icon-success@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F102AF22912009AE3D3 /* icon-success@2x.png */; };
19 | B5501F1A2AF22912009AE3D3 /* icon-error@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F112AF22912009AE3D3 /* icon-error@3x.png */; };
20 | B5501F1B2AF22912009AE3D3 /* icon-error@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F122AF22912009AE3D3 /* icon-error@2x.png */; };
21 | B5501F1C2AF22912009AE3D3 /* icon-success@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B5501F132AF22912009AE3D3 /* icon-success@3x.png */; };
22 | F22ADD2E1B8CB23F00EBA839 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = F22ADD2D1B8CB23F00EBA839 /* Message.swift */; };
23 | F283F61C25237BAC003DB4CF /* QueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F283F61B25237BAC003DB4CF /* QueueTests.swift */; };
24 | F283F61E25237BAC003DB4CF /* SwiftMessageBar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F2AB58E21B28B33C001DCC74 /* SwiftMessageBar.framework */; };
25 | F2AB58E81B28B33C001DCC74 /* SwiftMessageBar.h in Headers */ = {isa = PBXBuildFile; fileRef = F2AB58E71B28B33C001DCC74 /* SwiftMessageBar.h */; settings = {ATTRIBUTES = (Public, ); }; };
26 | F2AB593A1B28B45A001DCC74 /* SwiftMessageBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2AB59391B28B45A001DCC74 /* SwiftMessageBar.swift */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXContainerItemProxy section */
30 | F283F61F25237BAC003DB4CF /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = F2AB58D91B28B33C001DCC74 /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = F2AB58E11B28B33C001DCC74;
35 | remoteInfo = SwiftMessageBar;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXFileReference section */
40 | 77BBDF7D209705E600BDED60 /* DeviceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceType.swift; sourceTree = ""; };
41 | 77E9E14D205167C100E157F5 /* Queue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = ""; };
42 | 77EBFCB320519D5000AFE1F9 /* MessageType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageType.swift; sourceTree = ""; };
43 | B5501F0B2AF22912009AE3D3 /* icon-info@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-info@3x.png"; sourceTree = ""; };
44 | B5501F0C2AF22912009AE3D3 /* icon-success@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-success@1x.png"; sourceTree = ""; };
45 | B5501F0D2AF22912009AE3D3 /* icon-info@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-info@2x.png"; sourceTree = ""; };
46 | B5501F0E2AF22912009AE3D3 /* icon-error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-error.png"; sourceTree = ""; };
47 | B5501F0F2AF22912009AE3D3 /* icon-info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-info.png"; sourceTree = ""; };
48 | B5501F102AF22912009AE3D3 /* icon-success@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-success@2x.png"; sourceTree = ""; };
49 | B5501F112AF22912009AE3D3 /* icon-error@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-error@3x.png"; sourceTree = ""; };
50 | B5501F122AF22912009AE3D3 /* icon-error@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-error@2x.png"; sourceTree = ""; };
51 | B5501F132AF22912009AE3D3 /* icon-success@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-success@3x.png"; sourceTree = ""; };
52 | F22ADD2D1B8CB23F00EBA839 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = ""; };
53 | F283F61925237BAC003DB4CF /* SwiftMessageBarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftMessageBarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
54 | F283F61B25237BAC003DB4CF /* QueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueTests.swift; sourceTree = ""; };
55 | F283F61D25237BAC003DB4CF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
56 | F2AB58E21B28B33C001DCC74 /* SwiftMessageBar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftMessageBar.framework; sourceTree = BUILT_PRODUCTS_DIR; };
57 | F2AB58E61B28B33C001DCC74 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
58 | F2AB58E71B28B33C001DCC74 /* SwiftMessageBar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftMessageBar.h; sourceTree = ""; };
59 | F2AB59391B28B45A001DCC74 /* SwiftMessageBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftMessageBar.swift; sourceTree = ""; };
60 | /* End PBXFileReference section */
61 |
62 | /* Begin PBXFrameworksBuildPhase section */
63 | F283F61625237BAC003DB4CF /* Frameworks */ = {
64 | isa = PBXFrameworksBuildPhase;
65 | buildActionMask = 2147483647;
66 | files = (
67 | F283F61E25237BAC003DB4CF /* SwiftMessageBar.framework in Frameworks */,
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | F2AB58DE1B28B33C001DCC74 /* Frameworks */ = {
72 | isa = PBXFrameworksBuildPhase;
73 | buildActionMask = 2147483647;
74 | files = (
75 | );
76 | runOnlyForDeploymentPostprocessing = 0;
77 | };
78 | /* End PBXFrameworksBuildPhase section */
79 |
80 | /* Begin PBXGroup section */
81 | B5501F0A2AF22912009AE3D3 /* Resources */ = {
82 | isa = PBXGroup;
83 | children = (
84 | B5501F0B2AF22912009AE3D3 /* icon-info@3x.png */,
85 | B5501F0C2AF22912009AE3D3 /* icon-success@1x.png */,
86 | B5501F0D2AF22912009AE3D3 /* icon-info@2x.png */,
87 | B5501F0E2AF22912009AE3D3 /* icon-error.png */,
88 | B5501F0F2AF22912009AE3D3 /* icon-info.png */,
89 | B5501F102AF22912009AE3D3 /* icon-success@2x.png */,
90 | B5501F112AF22912009AE3D3 /* icon-error@3x.png */,
91 | B5501F122AF22912009AE3D3 /* icon-error@2x.png */,
92 | B5501F132AF22912009AE3D3 /* icon-success@3x.png */,
93 | );
94 | path = Resources;
95 | sourceTree = "";
96 | };
97 | F283F61A25237BAC003DB4CF /* SwiftMessageBarTests */ = {
98 | isa = PBXGroup;
99 | children = (
100 | F283F61B25237BAC003DB4CF /* QueueTests.swift */,
101 | F283F61D25237BAC003DB4CF /* Info.plist */,
102 | );
103 | path = SwiftMessageBarTests;
104 | sourceTree = "";
105 | };
106 | F2AB58D81B28B33C001DCC74 = {
107 | isa = PBXGroup;
108 | children = (
109 | F2AB58E41B28B33C001DCC74 /* SwiftMessageBar */,
110 | F283F61A25237BAC003DB4CF /* SwiftMessageBarTests */,
111 | F2AB58E31B28B33C001DCC74 /* Products */,
112 | );
113 | indentWidth = 2;
114 | sourceTree = "";
115 | tabWidth = 2;
116 | };
117 | F2AB58E31B28B33C001DCC74 /* Products */ = {
118 | isa = PBXGroup;
119 | children = (
120 | F2AB58E21B28B33C001DCC74 /* SwiftMessageBar.framework */,
121 | F283F61925237BAC003DB4CF /* SwiftMessageBarTests.xctest */,
122 | );
123 | name = Products;
124 | sourceTree = "";
125 | };
126 | F2AB58E41B28B33C001DCC74 /* SwiftMessageBar */ = {
127 | isa = PBXGroup;
128 | children = (
129 | 77BBDF7D209705E600BDED60 /* DeviceType.swift */,
130 | F22ADD2D1B8CB23F00EBA839 /* Message.swift */,
131 | 77EBFCB320519D5000AFE1F9 /* MessageType.swift */,
132 | 77E9E14D205167C100E157F5 /* Queue.swift */,
133 | F2AB58E61B28B33C001DCC74 /* Info.plist */,
134 | B5501F0A2AF22912009AE3D3 /* Resources */,
135 | F2AB58E71B28B33C001DCC74 /* SwiftMessageBar.h */,
136 | F2AB59391B28B45A001DCC74 /* SwiftMessageBar.swift */,
137 | );
138 | path = SwiftMessageBar;
139 | sourceTree = "";
140 | };
141 | /* End PBXGroup section */
142 |
143 | /* Begin PBXHeadersBuildPhase section */
144 | F2AB58DF1B28B33C001DCC74 /* Headers */ = {
145 | isa = PBXHeadersBuildPhase;
146 | buildActionMask = 2147483647;
147 | files = (
148 | F2AB58E81B28B33C001DCC74 /* SwiftMessageBar.h in Headers */,
149 | );
150 | runOnlyForDeploymentPostprocessing = 0;
151 | };
152 | /* End PBXHeadersBuildPhase section */
153 |
154 | /* Begin PBXNativeTarget section */
155 | F283F61825237BAC003DB4CF /* SwiftMessageBarTests */ = {
156 | isa = PBXNativeTarget;
157 | buildConfigurationList = F283F62325237BAC003DB4CF /* Build configuration list for PBXNativeTarget "SwiftMessageBarTests" */;
158 | buildPhases = (
159 | F283F61525237BAC003DB4CF /* Sources */,
160 | F283F61625237BAC003DB4CF /* Frameworks */,
161 | F283F61725237BAC003DB4CF /* Resources */,
162 | );
163 | buildRules = (
164 | );
165 | dependencies = (
166 | F283F62025237BAC003DB4CF /* PBXTargetDependency */,
167 | );
168 | name = SwiftMessageBarTests;
169 | productName = SwiftMessageBarTests;
170 | productReference = F283F61925237BAC003DB4CF /* SwiftMessageBarTests.xctest */;
171 | productType = "com.apple.product-type.bundle.unit-test";
172 | };
173 | F2AB58E11B28B33C001DCC74 /* SwiftMessageBar */ = {
174 | isa = PBXNativeTarget;
175 | buildConfigurationList = F2AB58F81B28B33D001DCC74 /* Build configuration list for PBXNativeTarget "SwiftMessageBar" */;
176 | buildPhases = (
177 | F2AB58DD1B28B33C001DCC74 /* Sources */,
178 | F2AB58DE1B28B33C001DCC74 /* Frameworks */,
179 | F2AB58DF1B28B33C001DCC74 /* Headers */,
180 | F2AB58E01B28B33C001DCC74 /* Resources */,
181 | );
182 | buildRules = (
183 | );
184 | dependencies = (
185 | );
186 | name = SwiftMessageBar;
187 | productName = SwiftMessageBar;
188 | productReference = F2AB58E21B28B33C001DCC74 /* SwiftMessageBar.framework */;
189 | productType = "com.apple.product-type.framework";
190 | };
191 | /* End PBXNativeTarget section */
192 |
193 | /* Begin PBXProject section */
194 | F2AB58D91B28B33C001DCC74 /* Project object */ = {
195 | isa = PBXProject;
196 | attributes = {
197 | LastSwiftMigration = 0700;
198 | LastSwiftUpdateCheck = 1200;
199 | LastUpgradeCheck = 1200;
200 | ORGANIZATIONNAME = Schnaub;
201 | TargetAttributes = {
202 | F283F61825237BAC003DB4CF = {
203 | CreatedOnToolsVersion = 12.0;
204 | DevelopmentTeam = CPRVB9W254;
205 | ProvisioningStyle = Automatic;
206 | };
207 | F2AB58E11B28B33C001DCC74 = {
208 | CreatedOnToolsVersion = 6.3.2;
209 | LastSwiftMigration = 1020;
210 | };
211 | };
212 | };
213 | buildConfigurationList = F2AB58DC1B28B33C001DCC74 /* Build configuration list for PBXProject "SwiftMessageBar" */;
214 | compatibilityVersion = "Xcode 3.2";
215 | developmentRegion = en;
216 | hasScannedForEncodings = 0;
217 | knownRegions = (
218 | en,
219 | Base,
220 | );
221 | mainGroup = F2AB58D81B28B33C001DCC74;
222 | productRefGroup = F2AB58E31B28B33C001DCC74 /* Products */;
223 | projectDirPath = "";
224 | projectRoot = "";
225 | targets = (
226 | F2AB58E11B28B33C001DCC74 /* SwiftMessageBar */,
227 | F283F61825237BAC003DB4CF /* SwiftMessageBarTests */,
228 | );
229 | };
230 | /* End PBXProject section */
231 |
232 | /* Begin PBXResourcesBuildPhase section */
233 | F283F61725237BAC003DB4CF /* Resources */ = {
234 | isa = PBXResourcesBuildPhase;
235 | buildActionMask = 2147483647;
236 | files = (
237 | );
238 | runOnlyForDeploymentPostprocessing = 0;
239 | };
240 | F2AB58E01B28B33C001DCC74 /* Resources */ = {
241 | isa = PBXResourcesBuildPhase;
242 | buildActionMask = 2147483647;
243 | files = (
244 | B5501F1A2AF22912009AE3D3 /* icon-error@3x.png in Resources */,
245 | B5501F162AF22912009AE3D3 /* icon-info@2x.png in Resources */,
246 | B5501F1C2AF22912009AE3D3 /* icon-success@3x.png in Resources */,
247 | B5501F182AF22912009AE3D3 /* icon-info.png in Resources */,
248 | B5501F172AF22912009AE3D3 /* icon-error.png in Resources */,
249 | B5501F152AF22912009AE3D3 /* icon-success@1x.png in Resources */,
250 | B5501F142AF22912009AE3D3 /* icon-info@3x.png in Resources */,
251 | B5501F1B2AF22912009AE3D3 /* icon-error@2x.png in Resources */,
252 | B5501F192AF22912009AE3D3 /* icon-success@2x.png in Resources */,
253 | );
254 | runOnlyForDeploymentPostprocessing = 0;
255 | };
256 | /* End PBXResourcesBuildPhase section */
257 |
258 | /* Begin PBXSourcesBuildPhase section */
259 | F283F61525237BAC003DB4CF /* Sources */ = {
260 | isa = PBXSourcesBuildPhase;
261 | buildActionMask = 2147483647;
262 | files = (
263 | F283F61C25237BAC003DB4CF /* QueueTests.swift in Sources */,
264 | );
265 | runOnlyForDeploymentPostprocessing = 0;
266 | };
267 | F2AB58DD1B28B33C001DCC74 /* Sources */ = {
268 | isa = PBXSourcesBuildPhase;
269 | buildActionMask = 2147483647;
270 | files = (
271 | F2AB593A1B28B45A001DCC74 /* SwiftMessageBar.swift in Sources */,
272 | 77E9E14E205167C100E157F5 /* Queue.swift in Sources */,
273 | F22ADD2E1B8CB23F00EBA839 /* Message.swift in Sources */,
274 | 77EBFCB420519D5000AFE1F9 /* MessageType.swift in Sources */,
275 | 77BBDF7E209705E600BDED60 /* DeviceType.swift in Sources */,
276 | );
277 | runOnlyForDeploymentPostprocessing = 0;
278 | };
279 | /* End PBXSourcesBuildPhase section */
280 |
281 | /* Begin PBXTargetDependency section */
282 | F283F62025237BAC003DB4CF /* PBXTargetDependency */ = {
283 | isa = PBXTargetDependency;
284 | target = F2AB58E11B28B33C001DCC74 /* SwiftMessageBar */;
285 | targetProxy = F283F61F25237BAC003DB4CF /* PBXContainerItemProxy */;
286 | };
287 | /* End PBXTargetDependency section */
288 |
289 | /* Begin XCBuildConfiguration section */
290 | F283F62125237BAC003DB4CF /* Debug */ = {
291 | isa = XCBuildConfiguration;
292 | buildSettings = {
293 | CLANG_ANALYZER_NONNULL = YES;
294 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
295 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
296 | CLANG_ENABLE_OBJC_WEAK = YES;
297 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
298 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
299 | CODE_SIGN_STYLE = Automatic;
300 | DEBUG_INFORMATION_FORMAT = dwarf;
301 | DEVELOPMENT_TEAM = CPRVB9W254;
302 | GCC_C_LANGUAGE_STANDARD = gnu11;
303 | INFOPLIST_FILE = SwiftMessageBarTests/Info.plist;
304 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
305 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
306 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
307 | MTL_FAST_MATH = YES;
308 | PRODUCT_BUNDLE_IDENTIFIER = com.schnaub.SwiftMessageBarTests;
309 | PRODUCT_NAME = "$(TARGET_NAME)";
310 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
311 | SWIFT_VERSION = 5.0;
312 | TARGETED_DEVICE_FAMILY = "1,2";
313 | };
314 | name = Debug;
315 | };
316 | F283F62225237BAC003DB4CF /* Release */ = {
317 | isa = XCBuildConfiguration;
318 | buildSettings = {
319 | CLANG_ANALYZER_NONNULL = YES;
320 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
321 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
322 | CLANG_ENABLE_OBJC_WEAK = YES;
323 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
324 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
325 | CODE_SIGN_STYLE = Automatic;
326 | DEVELOPMENT_TEAM = CPRVB9W254;
327 | GCC_C_LANGUAGE_STANDARD = gnu11;
328 | INFOPLIST_FILE = SwiftMessageBarTests/Info.plist;
329 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
330 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
331 | MTL_FAST_MATH = YES;
332 | PRODUCT_BUNDLE_IDENTIFIER = com.schnaub.SwiftMessageBarTests;
333 | PRODUCT_NAME = "$(TARGET_NAME)";
334 | SWIFT_VERSION = 5.0;
335 | TARGETED_DEVICE_FAMILY = "1,2";
336 | };
337 | name = Release;
338 | };
339 | F2AB58F61B28B33D001DCC74 /* Debug */ = {
340 | isa = XCBuildConfiguration;
341 | buildSettings = {
342 | ALWAYS_SEARCH_USER_PATHS = NO;
343 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
345 | CLANG_CXX_LIBRARY = "libc++";
346 | CLANG_ENABLE_MODULES = YES;
347 | CLANG_ENABLE_OBJC_ARC = YES;
348 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
349 | CLANG_WARN_BOOL_CONVERSION = YES;
350 | CLANG_WARN_COMMA = YES;
351 | CLANG_WARN_CONSTANT_CONVERSION = YES;
352 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
354 | CLANG_WARN_EMPTY_BODY = YES;
355 | CLANG_WARN_ENUM_CONVERSION = YES;
356 | CLANG_WARN_INFINITE_RECURSION = YES;
357 | CLANG_WARN_INT_CONVERSION = YES;
358 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
359 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
360 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
361 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
362 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
363 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
364 | CLANG_WARN_STRICT_PROTOTYPES = YES;
365 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
366 | CLANG_WARN_UNREACHABLE_CODE = YES;
367 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
368 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
369 | COPY_PHASE_STRIP = NO;
370 | CURRENT_PROJECT_VERSION = 1;
371 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
372 | ENABLE_STRICT_OBJC_MSGSEND = YES;
373 | ENABLE_TESTABILITY = YES;
374 | GCC_C_LANGUAGE_STANDARD = gnu99;
375 | GCC_DYNAMIC_NO_PIC = NO;
376 | GCC_NO_COMMON_BLOCKS = YES;
377 | GCC_OPTIMIZATION_LEVEL = 0;
378 | GCC_PREPROCESSOR_DEFINITIONS = (
379 | "DEBUG=1",
380 | "$(inherited)",
381 | );
382 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
383 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
384 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
385 | GCC_WARN_UNDECLARED_SELECTOR = YES;
386 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
387 | GCC_WARN_UNUSED_FUNCTION = YES;
388 | GCC_WARN_UNUSED_VARIABLE = YES;
389 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
390 | MTL_ENABLE_DEBUG_INFO = YES;
391 | ONLY_ACTIVE_ARCH = YES;
392 | SDKROOT = iphoneos;
393 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
394 | SWIFT_VERSION = 4.0;
395 | TARGETED_DEVICE_FAMILY = "1,2";
396 | VERSIONING_SYSTEM = "apple-generic";
397 | VERSION_INFO_PREFIX = "";
398 | };
399 | name = Debug;
400 | };
401 | F2AB58F71B28B33D001DCC74 /* Release */ = {
402 | isa = XCBuildConfiguration;
403 | buildSettings = {
404 | ALWAYS_SEARCH_USER_PATHS = NO;
405 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
406 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
407 | CLANG_CXX_LIBRARY = "libc++";
408 | CLANG_ENABLE_MODULES = YES;
409 | CLANG_ENABLE_OBJC_ARC = YES;
410 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
411 | CLANG_WARN_BOOL_CONVERSION = YES;
412 | CLANG_WARN_COMMA = YES;
413 | CLANG_WARN_CONSTANT_CONVERSION = YES;
414 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
415 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
416 | CLANG_WARN_EMPTY_BODY = YES;
417 | CLANG_WARN_ENUM_CONVERSION = YES;
418 | CLANG_WARN_INFINITE_RECURSION = YES;
419 | CLANG_WARN_INT_CONVERSION = YES;
420 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
421 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
422 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
423 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
424 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
425 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
426 | CLANG_WARN_STRICT_PROTOTYPES = YES;
427 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
428 | CLANG_WARN_UNREACHABLE_CODE = YES;
429 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
430 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
431 | COPY_PHASE_STRIP = NO;
432 | CURRENT_PROJECT_VERSION = 1;
433 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
434 | ENABLE_NS_ASSERTIONS = NO;
435 | ENABLE_STRICT_OBJC_MSGSEND = YES;
436 | GCC_C_LANGUAGE_STANDARD = gnu99;
437 | GCC_NO_COMMON_BLOCKS = YES;
438 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
439 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
440 | GCC_WARN_UNDECLARED_SELECTOR = YES;
441 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
442 | GCC_WARN_UNUSED_FUNCTION = YES;
443 | GCC_WARN_UNUSED_VARIABLE = YES;
444 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
445 | MTL_ENABLE_DEBUG_INFO = NO;
446 | SDKROOT = iphoneos;
447 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
448 | SWIFT_VERSION = 4.0;
449 | TARGETED_DEVICE_FAMILY = "1,2";
450 | VALIDATE_PRODUCT = YES;
451 | VERSIONING_SYSTEM = "apple-generic";
452 | VERSION_INFO_PREFIX = "";
453 | };
454 | name = Release;
455 | };
456 | F2AB58F91B28B33D001DCC74 /* Debug */ = {
457 | isa = XCBuildConfiguration;
458 | buildSettings = {
459 | CLANG_ENABLE_MODULES = YES;
460 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
461 | DEFINES_MODULE = YES;
462 | DYLIB_COMPATIBILITY_VERSION = 1;
463 | DYLIB_CURRENT_VERSION = 1;
464 | DYLIB_INSTALL_NAME_BASE = "@rpath";
465 | INFOPLIST_FILE = SwiftMessageBar/Info.plist;
466 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
467 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
468 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
469 | PRODUCT_BUNDLE_IDENTIFIER = "com.schnaub.$(PRODUCT_NAME:rfc1034identifier)";
470 | PRODUCT_NAME = "$(TARGET_NAME)";
471 | SKIP_INSTALL = YES;
472 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
473 | SWIFT_VERSION = 5.0;
474 | };
475 | name = Debug;
476 | };
477 | F2AB58FA1B28B33D001DCC74 /* Release */ = {
478 | isa = XCBuildConfiguration;
479 | buildSettings = {
480 | CLANG_ENABLE_MODULES = YES;
481 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
482 | DEFINES_MODULE = YES;
483 | DYLIB_COMPATIBILITY_VERSION = 1;
484 | DYLIB_CURRENT_VERSION = 1;
485 | DYLIB_INSTALL_NAME_BASE = "@rpath";
486 | INFOPLIST_FILE = SwiftMessageBar/Info.plist;
487 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
488 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
489 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
490 | PRODUCT_BUNDLE_IDENTIFIER = "com.schnaub.$(PRODUCT_NAME:rfc1034identifier)";
491 | PRODUCT_NAME = "$(TARGET_NAME)";
492 | SKIP_INSTALL = YES;
493 | SWIFT_VERSION = 5.0;
494 | };
495 | name = Release;
496 | };
497 | /* End XCBuildConfiguration section */
498 |
499 | /* Begin XCConfigurationList section */
500 | F283F62325237BAC003DB4CF /* Build configuration list for PBXNativeTarget "SwiftMessageBarTests" */ = {
501 | isa = XCConfigurationList;
502 | buildConfigurations = (
503 | F283F62125237BAC003DB4CF /* Debug */,
504 | F283F62225237BAC003DB4CF /* Release */,
505 | );
506 | defaultConfigurationIsVisible = 0;
507 | defaultConfigurationName = Release;
508 | };
509 | F2AB58DC1B28B33C001DCC74 /* Build configuration list for PBXProject "SwiftMessageBar" */ = {
510 | isa = XCConfigurationList;
511 | buildConfigurations = (
512 | F2AB58F61B28B33D001DCC74 /* Debug */,
513 | F2AB58F71B28B33D001DCC74 /* Release */,
514 | );
515 | defaultConfigurationIsVisible = 0;
516 | defaultConfigurationName = Release;
517 | };
518 | F2AB58F81B28B33D001DCC74 /* Build configuration list for PBXNativeTarget "SwiftMessageBar" */ = {
519 | isa = XCConfigurationList;
520 | buildConfigurations = (
521 | F2AB58F91B28B33D001DCC74 /* Debug */,
522 | F2AB58FA1B28B33D001DCC74 /* Release */,
523 | );
524 | defaultConfigurationIsVisible = 0;
525 | defaultConfigurationName = Release;
526 | };
527 | /* End XCConfigurationList section */
528 | };
529 | rootObject = F2AB58D91B28B33C001DCC74 /* Project object */;
530 | }
531 |
--------------------------------------------------------------------------------
/SwiftMessageBar.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftMessageBar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SwiftMessageBar.xcodeproj/xcshareddata/xcschemes/SwiftMessageBar.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
45 |
46 |
52 |
53 |
54 |
55 |
57 |
63 |
64 |
65 |
66 |
67 |
77 |
78 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/SwiftMessageBar.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftMessageBar.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SwiftMessageBar/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SwiftMessageBar/Message.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Schnaub. All rights reserved.
3 | //
4 |
5 | import UIKit
6 |
7 | final class Message: UIView {
8 |
9 | var isHit = false
10 |
11 | private(set) var type: MessageType!
12 | private let uuid = UUID()
13 | private var title: String?
14 | private var message: String?
15 | private var titleFontColor: UIColor!
16 | private var messageFontColor: UIColor!
17 | private var icon: UIImage?
18 | private(set) var callback: Callback?
19 | private(set) var duration: TimeInterval!
20 | private(set) var dismiss = true
21 | private var languageDirection: NSLocale.LanguageDirection!
22 | private var titleFont: UIFont!
23 | private var messageFont: UIFont!
24 | private var accessoryView: UIView?
25 |
26 | public lazy var contentStackView: UIStackView = {
27 | let contentView = UIStackView(frame: bounds)
28 | contentView.layoutMargins = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
29 | contentView.isLayoutMarginsRelativeArrangement = true
30 | contentView.axis = .horizontal
31 | contentView.spacing = 10
32 | return contentView
33 | }()
34 |
35 | private var paragraphStyle: NSMutableParagraphStyle {
36 | let paragraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
37 | paragraphStyle.alignment = .left
38 | return paragraphStyle
39 | }
40 |
41 | init(
42 | type: MessageType,
43 | title: String?,
44 | message: String?,
45 | backgroundColor: UIColor,
46 | titleFontColor: UIColor,
47 | messageFontColor: UIColor,
48 | icon: UIImage?,
49 | duration: TimeInterval,
50 | dismiss: Bool = true,
51 | callback: Callback?,
52 | languageDirection: NSLocale.LanguageDirection,
53 | titleFont: UIFont,
54 | messageFont: UIFont,
55 | accessoryView: UIView?
56 | ) {
57 | self.type = type
58 | self.title = title
59 | self.message = message
60 | self.duration = duration
61 | self.callback = callback
62 | self.titleFontColor = titleFontColor
63 | self.messageFontColor = messageFontColor
64 | self.icon = icon
65 | self.dismiss = dismiss
66 | self.languageDirection = languageDirection
67 | self.titleFont = titleFont
68 | self.messageFont = messageFont
69 | self.accessoryView = accessoryView
70 |
71 | super.init(frame: .zero)
72 |
73 | self.backgroundColor = backgroundColor
74 | usesAutoLayout(true)
75 | }
76 |
77 | func configureSubviews(topAnchor: NSLayoutYAxisAnchor) {
78 | let iconImageView = makeIconView()
79 | let titleLabel = makeTitleLabel()
80 | let messageLabel = makeMessageLabel()
81 |
82 | if languageDirection == .rightToLeft {
83 | titleLabel.textAlignment = .right
84 | messageLabel.textAlignment = .right
85 | titleLabel.flipHorizontal()
86 | messageLabel.flipHorizontal()
87 | iconImageView.flipHorizontal()
88 | accessoryView?.flipHorizontal()
89 | }
90 |
91 | let textStackView = makeTextStackView(with: titleLabel, messageLabel: messageLabel)
92 | contentStackView.addArrangedSubview(iconImageView)
93 | contentStackView.addArrangedSubview(textStackView)
94 |
95 | if let accessoryView = accessoryView {
96 | contentStackView.addArrangedSubview(makeWrapperView(for: accessoryView))
97 | }
98 |
99 | addSubview(contentStackView)
100 | configureConstraints(withTopAnchor: topAnchor)
101 | }
102 |
103 | private func configureConstraints(withTopAnchor topAnchor: NSLayoutYAxisAnchor) {
104 | contentStackView.usesAutoLayout(true)
105 | NSLayoutConstraint.activate([
106 | contentStackView.rightAnchor.constraint(equalTo: rightAnchor),
107 | contentStackView.leftAnchor.constraint(equalTo: leftAnchor),
108 | contentStackView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
109 | contentStackView.topAnchor.constraint(equalTo: topAnchor),
110 | ])
111 | }
112 |
113 | private func makeIconView() -> UIImageView {
114 | let iconImageView = UIImageView(image: icon)
115 | iconImageView.contentMode = .center
116 | iconImageView.setContentCompressionResistancePriority(.required, for: .horizontal)
117 | iconImageView.setContentHuggingPriority(.required, for: .horizontal)
118 | return iconImageView
119 | }
120 |
121 | private func makeTitleLabel() -> UILabel {
122 | let titleLabel = UILabel()
123 | titleLabel.numberOfLines = 0
124 |
125 | if let title = title {
126 | let attributes: [NSAttributedString.Key: Any] = [
127 | .font : titleFont!,
128 | .foregroundColor: titleFontColor!,
129 | .paragraphStyle: paragraphStyle
130 | ]
131 | titleLabel.attributedText = NSAttributedString(string: title, attributes: attributes)
132 | }
133 | return titleLabel
134 | }
135 |
136 | private func makeMessageLabel() -> UILabel {
137 | let messageLabel = UILabel()
138 | messageLabel.numberOfLines = 0
139 |
140 | if let message = message {
141 | let attributes: [NSAttributedString.Key: Any] = [
142 | .font : messageFont!,
143 | .foregroundColor: messageFontColor!,
144 | .paragraphStyle: paragraphStyle
145 | ]
146 | messageLabel.attributedText = NSAttributedString(string: message, attributes: attributes)
147 | }
148 | return messageLabel
149 | }
150 |
151 | private func makeTextStackView(with titleLabel: UILabel, messageLabel: UILabel) -> UIStackView {
152 | let isTitleEmpty = title?.isEmpty ?? true
153 | let isMessageEmpty = message?.isEmpty ?? true
154 |
155 | let stackView = UIStackView(frame: bounds)
156 | if !isTitleEmpty {
157 | stackView.addArrangedSubview(titleLabel)
158 | }
159 | if !isMessageEmpty {
160 | stackView.addArrangedSubview(messageLabel)
161 | }
162 |
163 | stackView.usesAutoLayout(true)
164 | stackView.axis = .vertical
165 | stackView.spacing = 1
166 | stackView.distribution = .fill
167 | return stackView
168 | }
169 |
170 | private func makeWrapperView(for view: UIView) -> UIView {
171 | let wrapper = UIView(frame: view.bounds)
172 |
173 | view.setContentCompressionResistancePriority(.required, for: .horizontal)
174 | wrapper.addSubview(view)
175 | wrapper.contentMode = .center
176 | NSLayoutConstraint.activate([
177 | view.centerYAnchor.constraint(equalTo: wrapper.centerYAnchor),
178 | view.centerXAnchor.constraint(equalTo: wrapper.centerXAnchor),
179 | view.widthAnchor.constraint(equalTo: wrapper.widthAnchor)])
180 |
181 | view.usesAutoLayout(true)
182 | return wrapper
183 | }
184 |
185 | required init?(coder aDecoder: NSCoder) {
186 | super.init(coder: aDecoder)
187 | }
188 |
189 | override func updateConstraints() {
190 | if let superview = superview {
191 | NSLayoutConstraint.activate([
192 | rightAnchor.constraint(equalTo: superview.rightAnchor),
193 | leftAnchor.constraint(equalTo: superview.leftAnchor),
194 | topAnchor.constraint(equalTo: superview.topAnchor)
195 | ])
196 | }
197 | super.updateConstraints()
198 | }
199 |
200 | var estimatedHeight: CGFloat {
201 | self.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
202 | }
203 | }
204 |
205 | extension Message: Identifiable {
206 |
207 | var id: UUID {
208 | uuid
209 | }
210 |
211 | }
212 |
213 | extension UIView {
214 |
215 | func flipHorizontal() {
216 | layer.setAffineTransform(CGAffineTransform(scaleX: -1, y: 1))
217 | }
218 |
219 | fileprivate func usesAutoLayout(_ usesAutoLayout: Bool) {
220 | translatesAutoresizingMaskIntoConstraints = !usesAutoLayout
221 | }
222 | }
223 |
224 |
--------------------------------------------------------------------------------
/SwiftMessageBar/MessageType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2018 Schnaub. All rights reserved.
3 | //
4 |
5 | import UIKit
6 |
7 | public enum MessageType {
8 | case error, success, info
9 |
10 | func backgroundColor(fromConfig config: SwiftMessageBar.Config) -> UIColor {
11 | switch self {
12 | case .error:
13 | return config.errorColor
14 | case .info:
15 | return config.infoColor
16 | case .success:
17 | return config.successColor
18 | }
19 | }
20 |
21 | func image(fromConfig config: SwiftMessageBar.Config) -> UIImage? {
22 | switch self {
23 | case .error:
24 | return config.errorIcon
25 | case .info:
26 | return config.infoIcon
27 | case .success:
28 | return config.successIcon
29 | }
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/SwiftMessageBar/Queue.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2018 Schnaub. All rights reserved.
3 | //
4 |
5 | import Foundation
6 |
7 | struct Queue {
8 |
9 | private var left: [T]
10 | private var right: [T]
11 |
12 | var isEmpty: Bool {
13 | left.isEmpty && right.isEmpty
14 | }
15 |
16 | init() {
17 | left = []
18 | right = []
19 | }
20 |
21 | mutating func dequeue() -> T? {
22 | guard !(left.isEmpty && right.isEmpty) else {
23 | return nil
24 | }
25 |
26 | if left.isEmpty {
27 | left = right.reversed()
28 | right.removeAll(keepingCapacity: true)
29 | }
30 | return left.removeLast()
31 | }
32 |
33 | mutating func enqueue(_ newElement: T) {
34 | right.append(newElement)
35 | }
36 |
37 | mutating func removeAll() {
38 | left.removeAll()
39 | right.removeAll()
40 | }
41 |
42 | mutating func removeElement(_ element: T) {
43 | if let idx = left.firstIndex(of: element) {
44 | left.remove(at: idx)
45 | }
46 | if let idx = right.firstIndex(of: element) {
47 | right.remove(at: idx)
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-error.png
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-error@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-error@2x.png
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-error@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-error@3x.png
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-info.png
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-info@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-info@2x.png
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-info@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-info@3x.png
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-success@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-success@1x.png
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-success@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-success@2x.png
--------------------------------------------------------------------------------
/SwiftMessageBar/Resources/icon-success@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JanGorman/SwiftMessageBar/0664a669264a11d7ba215c5cf6f18a2142d92394/SwiftMessageBar/Resources/icon-success@3x.png
--------------------------------------------------------------------------------
/SwiftMessageBar/SwiftMessageBar.h:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftMessageBar.h
3 | // SwiftMessageBar
4 | //
5 | // Created by Jan Gorman on 10/06/15.
6 | // Copyright (c) 2015 Schnaub. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for SwiftMessageBar.
12 | FOUNDATION_EXPORT double SwiftMessageBarVersionNumber;
13 |
14 | //! Project version string for SwiftMessageBar.
15 | FOUNDATION_EXPORT const unsigned char SwiftMessageBarVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/SwiftMessageBar/SwiftMessageBar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2015 Schnaub. All rights reserved.
3 | //
4 |
5 | import UIKit
6 |
7 | public typealias Callback = () -> Void
8 |
9 | public final class SwiftMessageBar {
10 |
11 | public struct Config {
12 |
13 | public struct Defaults {
14 | public static let errorColor: UIColor = .red
15 | public static let successColor: UIColor = .green
16 | public static let infoColor: UIColor = .blue
17 | public static let titleColor: UIColor = .white
18 | public static let messageColor: UIColor = .white
19 | public static let isStatusBarHidden = false
20 | public static let titleFont: UIFont = .boldSystemFont(ofSize: 16)
21 | public static let messageFont: UIFont = .systemFont(ofSize: 14)
22 | public static let isHapticFeedbackEnabled = true
23 | public static let windowLevel:UIWindow.Level = .normal
24 | }
25 |
26 | let errorColor: UIColor
27 | let successColor: UIColor
28 | let infoColor: UIColor
29 | let titleColor: UIColor
30 | let messageColor: UIColor
31 | let isStatusBarHidden: Bool
32 | let successIcon: UIImage?
33 | let infoIcon: UIImage?
34 | let errorIcon: UIImage?
35 | let titleFont: UIFont
36 | let messageFont: UIFont
37 | let isHapticFeedbackEnabled: Bool
38 | let windowLevel: UIWindow.Level
39 |
40 | public init(
41 | errorColor: UIColor = Defaults.errorColor,
42 | successColor: UIColor = Defaults.successColor,
43 | infoColor: UIColor = Defaults.infoColor,
44 | titleColor: UIColor = Defaults.titleColor,
45 | messageColor: UIColor = Defaults.messageColor,
46 | isStatusBarHidden: Bool = Defaults.isStatusBarHidden,
47 | successIcon: UIImage? = nil,
48 | infoIcon: UIImage? = nil,
49 | errorIcon: UIImage? = nil,
50 | titleFont: UIFont = Defaults.titleFont,
51 | messageFont: UIFont = Defaults.messageFont,
52 | isHapticFeedbackEnabled: Bool = Defaults.isHapticFeedbackEnabled,
53 | windowLevel: UIWindow.Level = Defaults.windowLevel
54 | ) {
55 | self.errorColor = errorColor
56 | self.successColor = successColor
57 | self.infoColor = infoColor
58 | self.titleColor = titleColor
59 | self.messageColor = messageColor
60 | self.isStatusBarHidden = isStatusBarHidden
61 | let bundle: Bundle
62 | #if SWIFT_PACKAGE
63 | bundle = Bundle.module
64 | #else
65 | bundle = Bundle(for: SwiftMessageBar.self)
66 | #endif
67 | self.successIcon = successIcon ?? UIImage(named: "icon-success", in: bundle, compatibleWith: nil)
68 | self.infoIcon = infoIcon ?? UIImage(named: "icon-info", in: bundle, compatibleWith: nil)
69 | self.errorIcon = errorIcon ?? UIImage(named: "icon-error", in: bundle, compatibleWith: nil)
70 | self.titleFont = titleFont
71 | self.messageFont = messageFont
72 | self.isHapticFeedbackEnabled = isHapticFeedbackEnabled
73 | self.windowLevel = windowLevel
74 | }
75 |
76 | public class Builder {
77 |
78 | private var errorColor: UIColor?
79 | private var successColor: UIColor?
80 | private var infoColor: UIColor?
81 | private var titleColor: UIColor?
82 | private var messageColor: UIColor?
83 | private var isStatusBarHidden: Bool?
84 | private var successIcon: UIImage?
85 | private var infoIcon: UIImage?
86 | private var errorIcon: UIImage?
87 | private var titleFont: UIFont?
88 | private var messageFont: UIFont?
89 | private var isHapticFeedbackEnabled: Bool?
90 | private var windowLevel: UIWindow.Level?
91 |
92 | public init() {}
93 |
94 | public func withErrorColor(_ color: UIColor) -> Builder {
95 | errorColor = color
96 | return self
97 | }
98 |
99 | public func withSuccessColor(_ color: UIColor) -> Builder {
100 | successColor = color
101 | return self
102 | }
103 |
104 | public func withInfoColor(_ color: UIColor) -> Builder {
105 | infoColor = color
106 | return self
107 | }
108 |
109 | public func withTitleColor(_ color: UIColor) -> Builder {
110 | titleColor = color
111 | return self
112 | }
113 |
114 | public func withMessageColor(_ color: UIColor) -> Builder {
115 | messageColor = color
116 | return self
117 | }
118 |
119 | public func withStatusBarHidden(_ isHidden: Bool) -> Builder {
120 | isStatusBarHidden = isHidden
121 | return self
122 | }
123 |
124 | public func withSuccessIcon(_ icon: UIImage) -> Builder {
125 | successIcon = icon
126 | return self
127 | }
128 |
129 | public func withInfoIcon(_ icon: UIImage) -> Builder {
130 | infoIcon = icon
131 | return self
132 | }
133 |
134 | public func withErrorIcon(_ icon: UIImage) -> Builder {
135 | errorIcon = icon
136 | return self
137 | }
138 |
139 | public func withTitleFont(_ font: UIFont) -> Builder {
140 | titleFont = font
141 | return self
142 | }
143 |
144 | public func withMessageFont(_ font: UIFont) -> Builder {
145 | messageFont = font
146 | return self
147 | }
148 |
149 | public func withHapticFeedbackEnabled(_ isEnabled: Bool) -> Builder {
150 | isHapticFeedbackEnabled = isEnabled
151 | return self
152 | }
153 |
154 | public func withWindowLevel(_ level: UIWindow.Level) -> Builder {
155 | windowLevel = level
156 | return self
157 | }
158 |
159 | public func build() -> Config {
160 | Config(
161 | errorColor: errorColor ?? Defaults.errorColor,
162 | successColor: successColor ?? Defaults.successColor,
163 | infoColor: infoColor ?? Defaults.infoColor,
164 | titleColor: titleColor ?? Defaults.titleColor,
165 | messageColor: messageColor ?? Defaults.messageColor,
166 | isStatusBarHidden: isStatusBarHidden ?? Defaults.isStatusBarHidden,
167 | successIcon: successIcon, infoIcon: infoIcon, errorIcon: errorIcon,
168 | titleFont: titleFont ?? Defaults.titleFont,
169 | messageFont: messageFont ?? Defaults.messageFont,
170 | isHapticFeedbackEnabled: isHapticFeedbackEnabled ?? Defaults.isHapticFeedbackEnabled,
171 | windowLevel: windowLevel ?? Defaults.windowLevel
172 | )
173 | }
174 |
175 | }
176 |
177 | }
178 |
179 | public static let sharedMessageBar = SwiftMessageBar()
180 |
181 | private static let showHideDuration: TimeInterval = 0.25
182 |
183 | private var config: Config
184 | private var messageWindow: MessageWindow?
185 | private var timer: Timer?
186 |
187 | public var tapHandler : (() -> Void)?
188 |
189 | private func newMessageWindow() -> MessageWindow {
190 | let messageWindow = MessageWindow()
191 | messageWindow.frame = UIScreen.main.bounds
192 | messageWindow.isHidden = false
193 | messageWindow.windowLevel = config.windowLevel
194 | messageWindow.backgroundColor = .clear
195 | messageWindow.messageBarController.statusBarHidden = config.isStatusBarHidden
196 | messageWindow.rootViewController = messageWindow.messageBarController
197 | return messageWindow
198 | }
199 |
200 | private var messageQueue: Queue
201 | private var isMessageVisible = false
202 |
203 | private init() {
204 | messageQueue = Queue()
205 | config = Config()
206 | }
207 |
208 | /// Set a message bar configuration used by all displayed messages.
209 | public static func setSharedConfig(_ config: Config) {
210 | sharedMessageBar.config = config
211 | }
212 |
213 | /// Display a message
214 | ///
215 | /// - Parameters:
216 | /// - title: An optional title
217 | /// - message: An optional message
218 | /// - type: The message type
219 | /// - duration: The time interval in seconds to show the message for
220 | /// - dismiss: Does the message automatically dismiss or not
221 | /// - languageDirection: Set an optional language direction if you require RTL support outside of what the system provides
222 | /// i.e. no need to set this parameter when NSLocale already is set to the proper languageDirection
223 | /// - accessoryView: An optional view to show in the right of the Message Bar
224 | /// - callback: An optional callback to execute when the user taps on a message to dismiss it.
225 | /// - Returns: A UUID for the message. Can be used to cancel the display of a specific message
226 | @discardableResult
227 | public static func showMessage(
228 | withTitle title: String? = nil,
229 | message: String? = nil,
230 | type: MessageType,
231 | duration: TimeInterval = 3,
232 | dismiss: Bool = true,
233 | languageDirection: NSLocale.LanguageDirection = .unknown,
234 | accessoryView: UIView? = nil,
235 | callback: Callback? = nil
236 | ) -> UUID {
237 | sharedMessageBar.showMessage(
238 | withTitle: title,
239 | message: message,
240 | type: type,
241 | duration: duration,
242 | dismiss: dismiss,
243 | languageDirection: languageDirection,
244 | accessoryView: accessoryView,
245 | callback: callback
246 | )
247 | }
248 |
249 | /// Display a message
250 | ///
251 | /// - Parameters:
252 | /// - title: An optional title
253 | /// - message: An optional message
254 | /// - type: The message type
255 | /// - duration: The time interval in seconds to show the message for
256 | /// - dismiss: Does the message automatically dismiss or not
257 | /// - languageDirection: Set an optional language direction if you require RTL support outside of what the system provides
258 | /// i.e. no need to set this parameter when NSLocale already is set to the proper languageDirection
259 | /// - accessoryView: An optional view to show in the right of the Message Bar
260 | /// - callback: An optional callback to execute when the user taps on a message to dismiss it.
261 | /// - Returns: A UUID for the message. Can be used to cancel the display of a specific message
262 | @discardableResult
263 | public func showMessage(
264 | withTitle title: String? = nil,
265 | message: String? = nil,
266 | type: MessageType,
267 | duration: TimeInterval = 3,
268 | dismiss: Bool = true,
269 | languageDirection: NSLocale.LanguageDirection = .unknown,
270 | accessoryView: UIView? = nil,
271 | callback: Callback? = nil
272 | ) -> UUID {
273 | let message = Message(
274 | type: type,
275 | title: title,
276 | message: message,
277 | backgroundColor: type.backgroundColor(fromConfig: config),
278 | titleFontColor: config.titleColor,
279 | messageFontColor: config.messageColor,
280 | icon: type.image(fromConfig: config),
281 | duration: duration,
282 | dismiss: dismiss,
283 | callback: callback,
284 | languageDirection: languageDirection,
285 | titleFont: config.titleFont,
286 | messageFont: config.messageFont,
287 | accessoryView: accessoryView
288 | )
289 | if languageDirection == .rightToLeft {
290 | message.flipHorizontal()
291 | }
292 | messageQueue.enqueue(message)
293 | if !isMessageVisible {
294 | dequeueNextMessage()
295 | }
296 | return message.id
297 | }
298 |
299 | /// Cancels the display of all messages.
300 | ///
301 | /// - Parameter force: A boolean to force immediate dismissal (without animation). Defaults to `false`
302 | public func cancelAll(force: Bool = false) {
303 | guard !isMessageVisible && messageQueue.isEmpty || force else { return }
304 |
305 | if let message = visibleMessage {
306 | if force {
307 | message.removeFromSuperview()
308 | messageWindow = nil
309 | } else {
310 | dismissMessage(message)
311 | }
312 | }
313 | resetTimer()
314 | isMessageVisible = false
315 | messageQueue.removeAll()
316 | }
317 |
318 | /// Cancels the display of a specific message
319 | ///
320 | /// - Parameter id: The UUID of the message to cancel.
321 | public func cancel(withId id: UUID) {
322 | if let message = visibleMessage, message.id == id {
323 | dismissMessage(message)
324 | messageQueue.removeElement(message)
325 | }
326 | }
327 |
328 | private var visibleMessage: Message? {
329 | messageWindow?.messageBarView.subviews.compactMap { $0 as? Message }.first
330 | }
331 |
332 | private func dequeueNextMessage() {
333 | guard let message = messageQueue.dequeue() else { return }
334 |
335 | let messageWindow: MessageWindow
336 | if let existensWindow = self.messageWindow {
337 | messageWindow = existensWindow
338 | } else {
339 | messageWindow = newMessageWindow()
340 | self.messageWindow = messageWindow
341 | }
342 |
343 | messageWindow.messageBarView.addSubview(message)
344 | messageWindow.messageBarView.bringSubviewToFront(message)
345 | isMessageVisible = true
346 |
347 | if #available(iOS 11, *) {
348 | message.configureSubviews(topAnchor: messageWindow.messageBarView.safeAreaLayoutGuide.topAnchor)
349 | } else {
350 | message.configureSubviews(topAnchor: messageWindow.messageBarController.topLayoutGuide.bottomAnchor)
351 | }
352 |
353 | message.setNeedsUpdateConstraints()
354 |
355 | let gesture = UITapGestureRecognizer(target: self, action: #selector(tap))
356 | message.addGestureRecognizer(gesture)
357 |
358 | message.transform = CGAffineTransform(translationX: 0, y: -messageWindow.frame.height)
359 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
360 | message.transform = CGAffineTransform(translationX: 0, y: -message.frame.height)
361 | UIView.animate(
362 | withDuration: SwiftMessageBar.showHideDuration,
363 | animations: {
364 | message.transform = .identity
365 | },
366 | completion: { _ in
367 | self.provideHapticFeedback(for: message)
368 | }
369 | )
370 | }
371 |
372 | if message.dismiss {
373 | resetTimer()
374 | timer = Timer.scheduledTimer(
375 | timeInterval: message.duration,
376 | target: self,
377 | selector: #selector(dismiss),
378 | userInfo: nil,
379 | repeats: false
380 | )
381 | }
382 | }
383 |
384 | private func provideHapticFeedback(for message: Message) {
385 | if #available(iOS 10.0, *), config.isHapticFeedbackEnabled && DeviceType.isPhone {
386 | let generator = UINotificationFeedbackGenerator()
387 | switch message.type! {
388 | case .error:
389 | generator.notificationOccurred(.error)
390 | case .info:
391 | generator.notificationOccurred(.warning)
392 | case .success:
393 | generator.notificationOccurred(.success)
394 | }
395 | }
396 | }
397 |
398 | private func resetTimer() {
399 | timer?.invalidate()
400 | timer = nil
401 | }
402 |
403 | @objc
404 | private func dismiss() {
405 | resetTimer()
406 | if let message = visibleMessage {
407 | dismissMessage(message)
408 | }
409 | }
410 |
411 | private func dismissMessage(_ message: Message) {
412 | dismissMessage(message, fromGesture: false)
413 | }
414 |
415 | @objc
416 | private func tap(_ gesture: UITapGestureRecognizer) {
417 | let message = gesture.view as! Message
418 | dismissMessage(message, fromGesture: true)
419 | tapHandler?()
420 | }
421 |
422 | private func dismissMessage(_ message: Message, fromGesture: Bool) {
423 | if message.isHit {
424 | return
425 | }
426 |
427 | message.isHit = true
428 |
429 | UIView.animate(
430 | withDuration: SwiftMessageBar.showHideDuration,
431 | delay: 0,
432 | options: [],
433 | animations: {
434 | message.transform = CGAffineTransform(translationX: 0, y: -message.frame.height)
435 | },
436 | completion: { [weak self] _ in
437 | self?.isMessageVisible = false
438 | message.removeFromSuperview()
439 |
440 | if fromGesture {
441 | message.callback?()
442 | }
443 |
444 | if let messageBar = self ,
445 | !messageBar.messageQueue.isEmpty {
446 | messageBar.dequeueNextMessage()
447 | } else {
448 | self?.resetTimer()
449 | self?.messageWindow = nil
450 | }
451 | }
452 | )
453 | }
454 |
455 | }
456 |
457 | private class MessageWindow: UIWindow {
458 |
459 | lazy var messageBarController = MessageBarController()
460 |
461 | var messageBarView: UIView {
462 | messageBarController.view
463 | }
464 |
465 | override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
466 | var hitView = super.hitTest(point, with: event)
467 | if hitView == rootViewController?.view {
468 | hitView = nil
469 | }
470 | return hitView
471 | }
472 |
473 | }
474 |
475 | private class MessageBarController: UIViewController {
476 |
477 | var statusBarStyle: UIStatusBarStyle = .default {
478 | didSet {
479 | setNeedsStatusBarAppearanceUpdate()
480 | }
481 | }
482 |
483 | var statusBarHidden: Bool = false {
484 | didSet {
485 | setNeedsStatusBarAppearanceUpdate()
486 | }
487 | }
488 |
489 | override var preferredStatusBarStyle: UIStatusBarStyle {
490 | statusBarStyle
491 | }
492 |
493 | override var prefersStatusBarHidden: Bool {
494 | statusBarHidden
495 | }
496 |
497 | }
498 |
499 | private enum DeviceType {
500 | static let isPhone = UIDevice.current.userInterfaceIdiom == .phone
501 | }
502 |
--------------------------------------------------------------------------------
/SwiftMessageBarTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SwiftMessageBarTests/QueueTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2020 Schnaub. All rights reserved.
3 | //
4 |
5 | @testable import SwiftMessageBar
6 | import XCTest
7 |
8 | final class QueueTests: XCTestCase {
9 |
10 | func testEmpty() {
11 | var queue = Queue()
12 |
13 | XCTAssertTrue(queue.isEmpty)
14 | XCTAssertNil(queue.dequeue())
15 | }
16 |
17 | func testEnqueueDequeue() {
18 | var queue = Queue()
19 | queue.enqueue("foo")
20 | queue.enqueue("bar")
21 |
22 | XCTAssertEqual(queue.dequeue(), "foo")
23 | XCTAssertEqual(queue.dequeue(), "bar")
24 | XCTAssertNil(queue.dequeue())
25 | }
26 |
27 | func testRemoveAll() {
28 | var queue = Queue()
29 | queue.enqueue("foo")
30 | queue.enqueue("bar")
31 |
32 | queue.removeAll()
33 |
34 | XCTAssertNil(queue.dequeue())
35 | }
36 |
37 | func testRemoveElement() {
38 | var queue = Queue()
39 | queue.enqueue("foo")
40 | queue.enqueue("bar")
41 | queue.enqueue("baz")
42 | queue.enqueue("bat")
43 |
44 | queue.removeElement("foo")
45 |
46 | XCTAssertEqual(queue.dequeue(), "bar")
47 |
48 | queue.removeElement("baz")
49 |
50 | XCTAssertEqual(queue.dequeue(), "bat")
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------