├── .gitignore └── .gitignore ├── .swift-version ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTIONS.md ├── LICENSE ├── README.md ├── Screenshots ├── Screenshot-1-landscape.png ├── Screenshot-1.png └── Screenshot-2.png ├── Zingle.podspec └── Zingle ├── Zingle.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── Hemang.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── Hemang.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist └── Zingle ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── Contents.json └── warning-icon.imageset │ ├── Contents.json │ ├── warning@3x-1.png │ ├── warning@3x-2.png │ └── warning@3x.png ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist ├── Source └── Zingle.swift └── ViewController.swift /.gitignore/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/swift,xcode,objective-c 2 | 3 | ### Objective-C ### 4 | # Xcode 5 | # 6 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData/ 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata/ 22 | 23 | ## Other 24 | *.moved-aside 25 | *.xccheckout 26 | *.xcscmblueprint 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | *.dSYM.zip 32 | *.dSYM 33 | 34 | # CocoaPods - Refactored to standalone file 35 | 36 | 37 | # Carthage - Refactored to standalone file 38 | 39 | # fastlane 40 | # 41 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 42 | # screenshots whenever they are needed. 43 | # For more information about the recommended setup visit: 44 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 45 | 46 | fastlane/report.xml 47 | fastlane/Preview.html 48 | fastlane/screenshots 49 | fastlane/test_output 50 | 51 | # Code Injection 52 | # 53 | # After new code Injection tools there's a generated folder /iOSInjectionProject 54 | # https://github.com/johnno1962/injectionforxcode 55 | 56 | iOSInjectionProject/ 57 | 58 | ### Objective-C Patch ### 59 | 60 | ### Swift ### 61 | # Xcode 62 | # 63 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 64 | 65 | ## Build generated 66 | 67 | ## Various settings 68 | 69 | ## Other 70 | 71 | ## Obj-C/Swift specific 72 | 73 | ## Playgrounds 74 | timeline.xctimeline 75 | playground.xcworkspace 76 | 77 | # Swift Package Manager 78 | # 79 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 80 | # Packages/ 81 | # Package.pins 82 | .build/ 83 | 84 | # CocoaPods - Refactored to standalone file 85 | 86 | # Carthage - Refactored to standalone file 87 | 88 | # fastlane 89 | # 90 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 91 | # screenshots whenever they are needed. 92 | # For more information about the recommended setup visit: 93 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 94 | 95 | 96 | ### Xcode ### 97 | # Xcode 98 | # 99 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 100 | 101 | ## Build generated 102 | 103 | ## Various settings 104 | 105 | ## Other 106 | 107 | ### Xcode Patch ### 108 | *.xcodeproj/* 109 | !*.xcodeproj/project.pbxproj 110 | !*.xcodeproj/xcshareddata/ 111 | !*.xcworkspace/contents.xcworkspacedata 112 | /*.gcno 113 | 114 | # End of https://www.gitignore.io/api/swift,xcode,objective-c 115 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.0 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: swift 2 | osx_image: xcode9.2 3 | 4 | branches: 5 | only: 6 | - master 7 | 8 | script: 9 | - cd Zingle/ 10 | - xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | Latest release is available [here](https://github.com/hemangshah/Zingle/releases/latest). 6 | 7 | ## [1.3.0](https://github.com/hemangshah/Zingle/releases/tag/1.3.0) - Jan 09, 2018 8 | - Added Documentations. 9 | - Updated ZingleConfig. 10 | - Improvements. 11 | 12 | ## [1.2.0](https://github.com/hemangshah/Zingle/releases/tag/1.2.0) - Jan 07, 2018 13 | - Fixed: https://github.com/hemangshah/Zingle/issues/2 14 | 15 | ## [1.1.0](https://github.com/hemangshah/Zingle/releases/tag/1.1.0) - Jan 02, 2018 16 | - Improvements with UIViewController's extension support. 17 | 18 | ## [1.0.0](https://github.com/hemangshah/Zingle/releases/tag/1.0.0) - Dec 29, 2017 19 | - First Release. 20 | -------------------------------------------------------------------------------- /CONTRIBUTIONS.md: -------------------------------------------------------------------------------- 1 | Without these I couldn't have made a better Zingle. 2 | 3 | > In order of help received. 4 | 5 | 1. Stack Overflow posts. 6 | 2. [These lovely people who encouraged me to keep developing on the Zingle](https://github.com/hemangshah/Zingle/stargazers). 7 | 3. [These great people who raised issues and provided me enough informations to fixed it.](https://github.com/hemangshah/Zingle/issues?q=is%3Aissue+is%3Aclosed) 8 | 4. [... and this list shouldn't end without these very helpful contributors.](https://github.com/hemangshah/Zingle/graphs/contributors) 9 | 10 | **Thank you so much.** 💙 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Hemang Shah 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zingle 2 | 3 | Zingle – An alert will display underneath your UINavigationBar 🎅 4 | 5 | 💥 **Note:** Zingle has a dependency to have a `UINavigationController` in your app, which means it will not work/display in your app if you don't have a `UINavigationController` linked to a `UIViewController` in which you're planning to show an alert. However, it will get display even if the `UINavigationBar` is hidden for a particular `UIViewController`. 6 | 7 | [![Build Status](https://travis-ci.org/hemangshah/Zingle.svg?branch=master)](https://travis-ci.org/hemangshah/Zingle) 8 | ![License](https://img.shields.io/badge/License-MIT-lightgrey.svg) 9 | ![Platform](https://img.shields.io/badge/Platforms-iOS-red.svg) 10 | ![Swift 4.x](https://img.shields.io/badge/Swift-4.x-blue.svg) 11 | ![MadeWithLove](https://img.shields.io/badge/Made%20with%20%E2%9D%A4-India-green.svg) 12 | [![Awesome-Swift](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/matteocrippa/awesome-swift/) 13 | 14 | 1. [Screenshots](#screenshots) 15 | 2. [Features](#features) 16 | 3. [Installation](#installation) 17 | 4. [Setup](#setup) 18 | 5. [Usage](#usage) 19 | 6. [Credits](#credits) 20 | 7. [Thanks](#thank-you) 21 | 8. [License](#license) 22 | 23 | ## Screenshots 24 | 25 | 26 | 27 | 28 | 29 | 30 |
iPhone8+iPhoneX
Landscape
31 | 32 | ## Features 33 | 34 | 1. Easy to setup & Use 35 | 2. Dynamic Property Configurations. 36 | 3. Lightweight with zero dependencies. 37 | 38 | ## Installation 39 | 40 | 1. **Manually** – Add `Zingle.swift` file to your Project.
41 | 2. **CocoaPods** – `pod 'Zingle'` 42 | 43 | > You can read the [CHANGELOG](https://github.com/hemangshah/Zingle/blob/master/CHANGELOG.md) file for a particular release. 44 | 45 | ## Setup 46 | 47 | ````swift 48 | import Zingle 49 | ```` 50 | 51 | ## Usage 52 | 53 | ````swift 54 | Zingle.init(duration: 0.5, delay: 3) 55 | .message(message: "No Internet Connection.") 56 | .messageIcon(icon: #imageLiteral(resourceName: "warning-icon")) 57 | .messageColor(color: .white) 58 | .messageFont(font: UIFont.init(name: "AmericanTypewriter", size: 15.0)!) 59 |  .backgroundColor(color: UIColor.red) 60 | .show() 61 | ```` 62 | 63 | You can also use it with in-built extension to `UIViewController`. 64 | 65 | ````swift 66 | //Create ZingleConfig. 67 | let config = ZingleConfig() 68 | config.delay = 2.0 69 | config.duration = 1.0 70 | config.messageColor = UIColor.white 71 | config.messageFont = UIFont.init(name: "AmericanTypewriter", size: 15.0)! 72 | config.backgroundColor = UIColor.purple.withAlphaComponent(0.5) 73 | 74 | //Show Zingle with `self` (UIViewController) with custom configuration. 75 | self.zingle(message: "No Internet Connection.", withConfig: config) 76 | 77 | //or 78 | 79 | //Show Zingle with `self` (UIViewController) with default configuration. 80 | self.zingle(message: "No Internet Connection.") 81 | 82 | ```` 83 | You can [watch](https://github.com/hemangshah/Zingle/subscription) to Zingle to see continuous updates. Stay tuned. 84 | 85 | Have an idea for improvements of this class? 86 | Please open an [issue](https://github.com/hemangshah/Zingle/issues/new). 87 |     88 | ## Credits 89 | 90 | [Hemang Shah](https://about.me/hemang.shah) 91 | 92 | **You can shoot me an [email](http://www.google.com/recaptcha/mailhide/d?k=01IzGihUsyfigse2G9z80rBw==&c=vU7vyAaau8BctOAIJFwHVbKfgtIqQ4QLJaL73yhnB3k=) to contact.** 93 |   94 | ## Thank You!! 95 | 96 | See the [contributions](https://github.com/hemangshah/Zingle/blob/master/CONTRIBUTIONS.md) for details. 97 | 98 | ## License 99 | 100 | The MIT License (MIT) 101 | 102 | > Read the [LICENSE](https://github.com/hemangshah/Zingle/blob/master/LICENSE) file for details. 103 | -------------------------------------------------------------------------------- /Screenshots/Screenshot-1-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hemangshah/Zingle/3ce76f1f0b83ccaf8b5c84197c8314acdc7b30bc/Screenshots/Screenshot-1-landscape.png -------------------------------------------------------------------------------- /Screenshots/Screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hemangshah/Zingle/3ce76f1f0b83ccaf8b5c84197c8314acdc7b30bc/Screenshots/Screenshot-1.png -------------------------------------------------------------------------------- /Screenshots/Screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hemangshah/Zingle/3ce76f1f0b83ccaf8b5c84197c8314acdc7b30bc/Screenshots/Screenshot-2.png -------------------------------------------------------------------------------- /Zingle.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Zingle' 3 | s.module_name = 'Zingle' 4 | s.version = '1.3.0' 5 | s.summary = 'Zingle – An alert will display underneath your UINavigationBar 🎅' 6 | s.description = 'Want to show an alert under the UINavigationBar for various cases like No Internet? If yes, use Zingle.' 7 | s.homepage = 'https://github.com/hemangshah/Zingle' 8 | s.license = 'MIT' 9 | s.author = { 'hemangshah' => 'hemangshah.in@gmail.com' } 10 | s.source = { :git => 'https://github.com/hemangshah/Zingle.git', :tag => s.version.to_s } 11 | s.platform = :ios, '9.0' 12 | s.requires_arc = true 13 | s.source_files = 'Zingle/Zingle/Source/*.swift' 14 | end 15 | -------------------------------------------------------------------------------- /Zingle/Zingle.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6B5394121FF55CE400EEBF3E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5394111FF55CE400EEBF3E /* AppDelegate.swift */; }; 11 | 6B5394141FF55CE400EEBF3E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5394131FF55CE400EEBF3E /* ViewController.swift */; }; 12 | 6B5394171FF55CE400EEBF3E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6B5394151FF55CE400EEBF3E /* Main.storyboard */; }; 13 | 6B5394191FF55CE400EEBF3E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6B5394181FF55CE400EEBF3E /* Assets.xcassets */; }; 14 | 6B53941C1FF55CE400EEBF3E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6B53941A1FF55CE400EEBF3E /* LaunchScreen.storyboard */; }; 15 | 6B5394251FF55D0600EEBF3E /* Zingle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B5394241FF55D0600EEBF3E /* Zingle.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 6B53940E1FF55CE400EEBF3E /* Zingle.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Zingle.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 6B5394111FF55CE400EEBF3E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 21 | 6B5394131FF55CE400EEBF3E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 22 | 6B5394161FF55CE400EEBF3E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 23 | 6B5394181FF55CE400EEBF3E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 24 | 6B53941B1FF55CE400EEBF3E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 25 | 6B53941D1FF55CE400EEBF3E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 26 | 6B5394241FF55D0600EEBF3E /* Zingle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Zingle.swift; sourceTree = ""; }; 27 | /* End PBXFileReference section */ 28 | 29 | /* Begin PBXFrameworksBuildPhase section */ 30 | 6B53940B1FF55CE400EEBF3E /* Frameworks */ = { 31 | isa = PBXFrameworksBuildPhase; 32 | buildActionMask = 2147483647; 33 | files = ( 34 | ); 35 | runOnlyForDeploymentPostprocessing = 0; 36 | }; 37 | /* End PBXFrameworksBuildPhase section */ 38 | 39 | /* Begin PBXGroup section */ 40 | 6B5394051FF55CE400EEBF3E = { 41 | isa = PBXGroup; 42 | children = ( 43 | 6B5394101FF55CE400EEBF3E /* Zingle */, 44 | 6B53940F1FF55CE400EEBF3E /* Products */, 45 | ); 46 | sourceTree = ""; 47 | }; 48 | 6B53940F1FF55CE400EEBF3E /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 6B53940E1FF55CE400EEBF3E /* Zingle.app */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 6B5394101FF55CE400EEBF3E /* Zingle */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 6B5394231FF55CEB00EEBF3E /* Source */, 60 | 6B5394111FF55CE400EEBF3E /* AppDelegate.swift */, 61 | 6B5394131FF55CE400EEBF3E /* ViewController.swift */, 62 | 6B5394151FF55CE400EEBF3E /* Main.storyboard */, 63 | 6B5394181FF55CE400EEBF3E /* Assets.xcassets */, 64 | 6B53941A1FF55CE400EEBF3E /* LaunchScreen.storyboard */, 65 | 6B53941D1FF55CE400EEBF3E /* Info.plist */, 66 | ); 67 | path = Zingle; 68 | sourceTree = ""; 69 | }; 70 | 6B5394231FF55CEB00EEBF3E /* Source */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 6B5394241FF55D0600EEBF3E /* Zingle.swift */, 74 | ); 75 | path = Source; 76 | sourceTree = ""; 77 | }; 78 | /* End PBXGroup section */ 79 | 80 | /* Begin PBXNativeTarget section */ 81 | 6B53940D1FF55CE400EEBF3E /* Zingle */ = { 82 | isa = PBXNativeTarget; 83 | buildConfigurationList = 6B5394201FF55CE400EEBF3E /* Build configuration list for PBXNativeTarget "Zingle" */; 84 | buildPhases = ( 85 | 6B53940A1FF55CE400EEBF3E /* Sources */, 86 | 6B53940B1FF55CE400EEBF3E /* Frameworks */, 87 | 6B53940C1FF55CE400EEBF3E /* Resources */, 88 | ); 89 | buildRules = ( 90 | ); 91 | dependencies = ( 92 | ); 93 | name = Zingle; 94 | productName = Zingle; 95 | productReference = 6B53940E1FF55CE400EEBF3E /* Zingle.app */; 96 | productType = "com.apple.product-type.application"; 97 | }; 98 | /* End PBXNativeTarget section */ 99 | 100 | /* Begin PBXProject section */ 101 | 6B5394061FF55CE400EEBF3E /* Project object */ = { 102 | isa = PBXProject; 103 | attributes = { 104 | LastSwiftUpdateCheck = 0910; 105 | LastUpgradeCheck = 0910; 106 | ORGANIZATIONNAME = "Hemang Shah"; 107 | TargetAttributes = { 108 | 6B53940D1FF55CE400EEBF3E = { 109 | CreatedOnToolsVersion = 9.1; 110 | ProvisioningStyle = Automatic; 111 | }; 112 | }; 113 | }; 114 | buildConfigurationList = 6B5394091FF55CE400EEBF3E /* Build configuration list for PBXProject "Zingle" */; 115 | compatibilityVersion = "Xcode 8.0"; 116 | developmentRegion = en; 117 | hasScannedForEncodings = 0; 118 | knownRegions = ( 119 | en, 120 | Base, 121 | ); 122 | mainGroup = 6B5394051FF55CE400EEBF3E; 123 | productRefGroup = 6B53940F1FF55CE400EEBF3E /* Products */; 124 | projectDirPath = ""; 125 | projectRoot = ""; 126 | targets = ( 127 | 6B53940D1FF55CE400EEBF3E /* Zingle */, 128 | ); 129 | }; 130 | /* End PBXProject section */ 131 | 132 | /* Begin PBXResourcesBuildPhase section */ 133 | 6B53940C1FF55CE400EEBF3E /* Resources */ = { 134 | isa = PBXResourcesBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | 6B53941C1FF55CE400EEBF3E /* LaunchScreen.storyboard in Resources */, 138 | 6B5394191FF55CE400EEBF3E /* Assets.xcassets in Resources */, 139 | 6B5394171FF55CE400EEBF3E /* Main.storyboard in Resources */, 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | /* End PBXResourcesBuildPhase section */ 144 | 145 | /* Begin PBXSourcesBuildPhase section */ 146 | 6B53940A1FF55CE400EEBF3E /* Sources */ = { 147 | isa = PBXSourcesBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | 6B5394141FF55CE400EEBF3E /* ViewController.swift in Sources */, 151 | 6B5394121FF55CE400EEBF3E /* AppDelegate.swift in Sources */, 152 | 6B5394251FF55D0600EEBF3E /* Zingle.swift in Sources */, 153 | ); 154 | runOnlyForDeploymentPostprocessing = 0; 155 | }; 156 | /* End PBXSourcesBuildPhase section */ 157 | 158 | /* Begin PBXVariantGroup section */ 159 | 6B5394151FF55CE400EEBF3E /* Main.storyboard */ = { 160 | isa = PBXVariantGroup; 161 | children = ( 162 | 6B5394161FF55CE400EEBF3E /* Base */, 163 | ); 164 | name = Main.storyboard; 165 | sourceTree = ""; 166 | }; 167 | 6B53941A1FF55CE400EEBF3E /* LaunchScreen.storyboard */ = { 168 | isa = PBXVariantGroup; 169 | children = ( 170 | 6B53941B1FF55CE400EEBF3E /* Base */, 171 | ); 172 | name = LaunchScreen.storyboard; 173 | sourceTree = ""; 174 | }; 175 | /* End PBXVariantGroup section */ 176 | 177 | /* Begin XCBuildConfiguration section */ 178 | 6B53941E1FF55CE400EEBF3E /* Debug */ = { 179 | isa = XCBuildConfiguration; 180 | buildSettings = { 181 | ALWAYS_SEARCH_USER_PATHS = NO; 182 | CLANG_ANALYZER_NONNULL = YES; 183 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 184 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 185 | CLANG_CXX_LIBRARY = "libc++"; 186 | CLANG_ENABLE_MODULES = YES; 187 | CLANG_ENABLE_OBJC_ARC = YES; 188 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 189 | CLANG_WARN_BOOL_CONVERSION = YES; 190 | CLANG_WARN_COMMA = YES; 191 | CLANG_WARN_CONSTANT_CONVERSION = YES; 192 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 193 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 194 | CLANG_WARN_EMPTY_BODY = YES; 195 | CLANG_WARN_ENUM_CONVERSION = YES; 196 | CLANG_WARN_INFINITE_RECURSION = YES; 197 | CLANG_WARN_INT_CONVERSION = YES; 198 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 199 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 200 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 201 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 202 | CLANG_WARN_STRICT_PROTOTYPES = YES; 203 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 204 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 205 | CLANG_WARN_UNREACHABLE_CODE = YES; 206 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 207 | CODE_SIGN_IDENTITY = "iPhone Developer"; 208 | COPY_PHASE_STRIP = NO; 209 | DEBUG_INFORMATION_FORMAT = dwarf; 210 | ENABLE_STRICT_OBJC_MSGSEND = YES; 211 | ENABLE_TESTABILITY = YES; 212 | GCC_C_LANGUAGE_STANDARD = gnu11; 213 | GCC_DYNAMIC_NO_PIC = NO; 214 | GCC_NO_COMMON_BLOCKS = YES; 215 | GCC_OPTIMIZATION_LEVEL = 0; 216 | GCC_PREPROCESSOR_DEFINITIONS = ( 217 | "DEBUG=1", 218 | "$(inherited)", 219 | ); 220 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 221 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 222 | GCC_WARN_UNDECLARED_SELECTOR = YES; 223 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 224 | GCC_WARN_UNUSED_FUNCTION = YES; 225 | GCC_WARN_UNUSED_VARIABLE = YES; 226 | IPHONEOS_DEPLOYMENT_TARGET = 11.1; 227 | MTL_ENABLE_DEBUG_INFO = YES; 228 | ONLY_ACTIVE_ARCH = YES; 229 | SDKROOT = iphoneos; 230 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 231 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 232 | }; 233 | name = Debug; 234 | }; 235 | 6B53941F1FF55CE400EEBF3E /* Release */ = { 236 | isa = XCBuildConfiguration; 237 | buildSettings = { 238 | ALWAYS_SEARCH_USER_PATHS = NO; 239 | CLANG_ANALYZER_NONNULL = YES; 240 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 241 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 242 | CLANG_CXX_LIBRARY = "libc++"; 243 | CLANG_ENABLE_MODULES = YES; 244 | CLANG_ENABLE_OBJC_ARC = YES; 245 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 246 | CLANG_WARN_BOOL_CONVERSION = YES; 247 | CLANG_WARN_COMMA = YES; 248 | CLANG_WARN_CONSTANT_CONVERSION = YES; 249 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 250 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 251 | CLANG_WARN_EMPTY_BODY = YES; 252 | CLANG_WARN_ENUM_CONVERSION = YES; 253 | CLANG_WARN_INFINITE_RECURSION = YES; 254 | CLANG_WARN_INT_CONVERSION = YES; 255 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 258 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 259 | CLANG_WARN_STRICT_PROTOTYPES = YES; 260 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 261 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 262 | CLANG_WARN_UNREACHABLE_CODE = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | CODE_SIGN_IDENTITY = "iPhone Developer"; 265 | COPY_PHASE_STRIP = NO; 266 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 267 | ENABLE_NS_ASSERTIONS = NO; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | GCC_C_LANGUAGE_STANDARD = gnu11; 270 | GCC_NO_COMMON_BLOCKS = YES; 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 = 11.1; 278 | MTL_ENABLE_DEBUG_INFO = NO; 279 | SDKROOT = iphoneos; 280 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 281 | VALIDATE_PRODUCT = YES; 282 | }; 283 | name = Release; 284 | }; 285 | 6B5394211FF55CE400EEBF3E /* Debug */ = { 286 | isa = XCBuildConfiguration; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CODE_SIGN_STYLE = Automatic; 290 | INFOPLIST_FILE = Zingle/Info.plist; 291 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 292 | PRODUCT_BUNDLE_IDENTIFIER = com.hemangshah.Zingle; 293 | PRODUCT_NAME = "$(TARGET_NAME)"; 294 | SWIFT_VERSION = 4.0; 295 | TARGETED_DEVICE_FAMILY = "1,2"; 296 | }; 297 | name = Debug; 298 | }; 299 | 6B5394221FF55CE400EEBF3E /* Release */ = { 300 | isa = XCBuildConfiguration; 301 | buildSettings = { 302 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 303 | CODE_SIGN_STYLE = Automatic; 304 | INFOPLIST_FILE = Zingle/Info.plist; 305 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 306 | PRODUCT_BUNDLE_IDENTIFIER = com.hemangshah.Zingle; 307 | PRODUCT_NAME = "$(TARGET_NAME)"; 308 | SWIFT_VERSION = 4.0; 309 | TARGETED_DEVICE_FAMILY = "1,2"; 310 | }; 311 | name = Release; 312 | }; 313 | /* End XCBuildConfiguration section */ 314 | 315 | /* Begin XCConfigurationList section */ 316 | 6B5394091FF55CE400EEBF3E /* Build configuration list for PBXProject "Zingle" */ = { 317 | isa = XCConfigurationList; 318 | buildConfigurations = ( 319 | 6B53941E1FF55CE400EEBF3E /* Debug */, 320 | 6B53941F1FF55CE400EEBF3E /* Release */, 321 | ); 322 | defaultConfigurationIsVisible = 0; 323 | defaultConfigurationName = Release; 324 | }; 325 | 6B5394201FF55CE400EEBF3E /* Build configuration list for PBXNativeTarget "Zingle" */ = { 326 | isa = XCConfigurationList; 327 | buildConfigurations = ( 328 | 6B5394211FF55CE400EEBF3E /* Debug */, 329 | 6B5394221FF55CE400EEBF3E /* Release */, 330 | ); 331 | defaultConfigurationIsVisible = 0; 332 | defaultConfigurationName = Release; 333 | }; 334 | /* End XCConfigurationList section */ 335 | }; 336 | rootObject = 6B5394061FF55CE400EEBF3E /* Project object */; 337 | } 338 | -------------------------------------------------------------------------------- /Zingle/Zingle.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Zingle/Zingle.xcodeproj/project.xcworkspace/xcuserdata/Hemang.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hemangshah/Zingle/3ce76f1f0b83ccaf8b5c84197c8314acdc7b30bc/Zingle/Zingle.xcodeproj/project.xcworkspace/xcuserdata/Hemang.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Zingle/Zingle.xcodeproj/xcuserdata/Hemang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Zingle/Zingle.xcodeproj/xcuserdata/Hemang.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Zingle.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Zingle/Zingle/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Zingle 4 | // 5 | // Created by Hemang on 28/12/17. 6 | // Copyright © 2017 Hemang Shah. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Zingle/Zingle/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Zingle/Zingle/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Zingle/Zingle/Assets.xcassets/warning-icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "warning@3x-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "warning@3x-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "warning@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Zingle/Zingle/Assets.xcassets/warning-icon.imageset/warning@3x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hemangshah/Zingle/3ce76f1f0b83ccaf8b5c84197c8314acdc7b30bc/Zingle/Zingle/Assets.xcassets/warning-icon.imageset/warning@3x-1.png -------------------------------------------------------------------------------- /Zingle/Zingle/Assets.xcassets/warning-icon.imageset/warning@3x-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hemangshah/Zingle/3ce76f1f0b83ccaf8b5c84197c8314acdc7b30bc/Zingle/Zingle/Assets.xcassets/warning-icon.imageset/warning@3x-2.png -------------------------------------------------------------------------------- /Zingle/Zingle/Assets.xcassets/warning-icon.imageset/warning@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hemangshah/Zingle/3ce76f1f0b83ccaf8b5c84197c8314acdc7b30bc/Zingle/Zingle/Assets.xcassets/warning-icon.imageset/warning@3x.png -------------------------------------------------------------------------------- /Zingle/Zingle/Base.lproj/LaunchScreen.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 | 25 | 26 | -------------------------------------------------------------------------------- /Zingle/Zingle/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 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Zingle/Zingle/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 | APPL 17 | CFBundleShortVersionString 18 | 1.3.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Zingle/Zingle/Source/Zingle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Zingle.swift 3 | // Zingle 4 | // 5 | // Created by Hemang on 28/12/17. 6 | // Copyright © 2017 Hemang Shah. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class ZingleConfig { 12 | public init() {} 13 | ///Set delay to hide Zingle. Default: 2.0. 14 | public var delay: TimeInterval = 2.0 15 | ///Set duration of Zingle visible animation. Default: 0.3. 16 | public var duration: TimeInterval = 0.3 17 | ///Set Zingle message color. Default: white. 18 | public var messageColor: UIColor = UIColor.white 19 | ///Set Zingle message font. Default: UIFont.systemFont(ofSize: 15). 20 | public var messageFont: UIFont = UIFont.systemFont(ofSize: 15) 21 | ///Set Zingle message icon. Default: Empty UIImage. 22 | public var messageIcon: UIImage! = UIImage.init() 23 | ///Set Zingle background color. Default: red. 24 | public var backgroundColor: UIColor = UIColor.red 25 | } 26 | 27 | public class Zingle: UIView { 28 | 29 | typealias CompletionBlock = () -> Void 30 | 31 | fileprivate var isZingleShowing: Bool = false 32 | fileprivate var delay: TimeInterval 33 | fileprivate var duration: TimeInterval 34 | fileprivate var completion: CompletionBlock? 35 | 36 | fileprivate var messageButton: UIButton = UIButton.init(type: .custom) 37 | fileprivate var messageColor: UIColor = UIColor.white 38 | fileprivate var messageFont: UIFont = UIFont.systemFont(ofSize: 15) 39 | 40 | fileprivate let heightForZingal: CGFloat = 30.0 41 | 42 | fileprivate var yPosForZingal: CGFloat { 43 | if let navigationController = ((UIApplication.shared.keyWindow?.rootViewController) as? UINavigationController) { 44 | return ((navigationController.navigationBar.intrinsicContentSize.height) 45 | + UIApplication.shared.statusBarFrame.height) 46 | } 47 | return 0.0 48 | } 49 | 50 | fileprivate var unhideYPositionForZingle: CGFloat { 51 | get { 52 | let yPos = self.yPosForZingal 53 | return yPos 54 | } 55 | } 56 | 57 | fileprivate var hiddenYPositionForZingle: CGFloat { 58 | get { 59 | let yPos = self.yPosForZingal - heightForZingal 60 | return yPos 61 | } 62 | } 63 | 64 | ///Init Zingle with Duration and Delay. Default Duration (0.3) Delay (2.0) 65 | public init(duration: TimeInterval = 0.3, delay: TimeInterval = 2.0) { 66 | 67 | self.completion = nil 68 | self.delay = delay 69 | self.duration = duration 70 | 71 | super.init(frame: CGRect.zero) 72 | 73 | self.setupZingle() 74 | } 75 | 76 | required public init?(coder aDecoder: NSCoder) { 77 | fatalError("init(coder:) has not been implemented") 78 | } 79 | } 80 | 81 | //MARK: UIViewController Extension 82 | public extension UIViewController { 83 | ///Show Zingle with config. 84 | public func zingle(message: String!, withConfig config: ZingleConfig!) { 85 | Zingle(duration: config.duration, delay: config.delay) 86 | .backgroundColor(color: config.backgroundColor) 87 | .message(message: message) 88 | .messageIcon(icon: config.messageIcon) 89 | .messageColor(color: config.messageColor) 90 | .messageFont(font: config.messageFont) 91 | .show() 92 | } 93 | 94 | ///Show Zingle with default config. 95 | public func zingle(message: String!) { 96 | let config = ZingleConfig() 97 | Zingle(duration: config.duration, delay: config.delay) 98 | .backgroundColor(color: config.backgroundColor) 99 | .message(message: message) 100 | .messageIcon(icon: config.messageIcon) 101 | .messageColor(color: config.messageColor) 102 | .messageFont(font: config.messageFont) 103 | .show() 104 | } 105 | } 106 | 107 | // MARK: setup function 108 | extension Zingle { 109 | fileprivate func setupZingle() { 110 | self.setupView() 111 | self.setupMessageButton() 112 | } 113 | 114 | fileprivate func setupView() { 115 | self.backgroundColor = UIColor.backgroundColor 116 | self.frame = CGRect(x: 0, y: self.hiddenYPositionForZingle, width: UIScreen.main.bounds.width, height: heightForZingal) 117 | } 118 | 119 | fileprivate func setupMessageButton() { 120 | self.messageButton.frame = CGRect(x: 0.0, y: 0.0, width: self.frame.size.width, height: self.frame.size.height) 121 | self.messageButton.setTitleColor(self.messageColor, for: .normal) 122 | self.messageButton.titleLabel?.font = self.messageFont 123 | self.messageButton.backgroundColor = UIColor.clear 124 | self.messageButton.setTitle("", for: .normal) 125 | self.messageButton.contentVerticalAlignment = .center 126 | self.messageButton.contentHorizontalAlignment = .center 127 | self.addSubview(self.messageButton) 128 | self.messageButton.centerTextAndImage(spacing: 5.0) 129 | } 130 | } 131 | 132 | // MARK: chaning function and show / hide functions 133 | public extension Zingle { 134 | 135 | ///Set Zingle message to display. 136 | public func message(message: String!) -> Self { 137 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + self.duration/4.0) { 138 | self.messageButton.setTitle(message, for: .normal) 139 | } 140 | return self 141 | } 142 | 143 | ///Set Zingle message icon. 144 | public func messageIcon(icon: UIImage!) -> Self { 145 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + self.duration/1.5) { 146 | self.messageButton.setImage(icon, for: .normal) 147 | } 148 | return self 149 | } 150 | 151 | ///Set Zingle message color. 152 | public func messageColor(color: UIColor!) -> Self { 153 | self.messageButton.setTitleColor(color, for: .normal) 154 | return self 155 | } 156 | 157 | ///Set Zingle background color. 158 | public func backgroundColor(color: UIColor!) -> Self { 159 | self.messageButton.backgroundColor = color 160 | return self 161 | } 162 | 163 | ///Set Zingle message font. 164 | public func messageFont(font: UIFont!) -> Self { 165 | self.messageButton.titleLabel?.font = font 166 | return self 167 | } 168 | 169 | ///Handle Zinlge completion. 170 | public func completion(_ completion: @escaping () -> Void) -> Self { 171 | self.completion = completion 172 | return self 173 | } 174 | 175 | ///Show Zingle. 176 | public func show() { 177 | self.adjustView() 178 | 179 | self.startAnimation { 180 | DispatchQueue.main.asyncAfter(deadline: .now() + self.delay) { 181 | self.finishAnimating() 182 | } 183 | } 184 | } 185 | } 186 | 187 | // MARK: animation functions 188 | extension Zingle { 189 | 190 | fileprivate func startAnimation(completion: @escaping () -> Void) { 191 | 192 | guard !self.isZingleShowing else { 193 | return 194 | } 195 | 196 | self.isZingleShowing = true 197 | self.alpha = 1.0 198 | 199 | UIView.animate(withDuration: duration, animations: { 200 | self.frame.origin.y = self.unhideYPositionForZingle 201 | self.layoutIfNeeded() 202 | }) { _ in 203 | completion() 204 | } 205 | } 206 | 207 | fileprivate func finishAnimating() { 208 | UIView.animate(withDuration: duration, animations: { 209 | self.frame.origin.y = self.hiddenYPositionForZingle 210 | self.alpha = 0.0 211 | self.layoutIfNeeded() 212 | }) { _ in 213 | self.isZingleShowing = false 214 | self.completion?() 215 | } 216 | } 217 | } 218 | 219 | // MARK: manage window hierarchy functions 220 | extension Zingle { 221 | 222 | fileprivate func adjustView() { 223 | self.addZingleViewInWindow() 224 | } 225 | 226 | fileprivate func addZingleViewInWindow() { 227 | guard let keyWindow = UIApplication.shared.keyWindow, 228 | let rootViewController = keyWindow.rootViewController as? UINavigationController else { 229 | return 230 | } 231 | let navigationBar = rootViewController.navigationBar 232 | rootViewController.view.insertSubview(self, belowSubview: navigationBar) 233 | } 234 | } 235 | 236 | // MARK: Extensions 237 | fileprivate extension UIColor { 238 | static var backgroundColor: UIColor { 239 | return UIColor(red: 35/255, green: 8/255, blue: 18/255, alpha: 1) 240 | } 241 | } 242 | 243 | fileprivate extension UIButton { 244 | func centerTextAndImage(spacing: CGFloat) { 245 | let insetAmount = spacing / 2 246 | let writingDirection = UIApplication.shared.userInterfaceLayoutDirection 247 | let factor: CGFloat = writingDirection == .leftToRight ? 1 : -1 248 | 249 | self.imageEdgeInsets = UIEdgeInsets(top: 0, left: -insetAmount*factor, bottom: 0, right: insetAmount*factor) 250 | self.titleEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount*factor, bottom: 0, right: -insetAmount*factor) 251 | self.contentEdgeInsets = UIEdgeInsets(top: 0, left: insetAmount, bottom: 0, right: insetAmount) 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /Zingle/Zingle/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Zingle 4 | // 5 | // Created by Hemang on 28/12/17. 6 | // Copyright © 2017 Hemang Shah. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | @IBAction func buttonTapped(_ sender: Any) { 13 | Zingle.init(duration: 0.5, delay: 3) 14 | .message(message: "No Internet Connection!") 15 | .messageIcon(icon: #imageLiteral(resourceName: "warning-icon")) 16 | .messageColor(color: .white) 17 | .messageFont(font: UIFont.init(name: "AmericanTypewriter", size: 15.0)!) 18 | .show() 19 | } 20 | } 21 | --------------------------------------------------------------------------------