├── .gitignore ├── .swiftlint.yml ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── AlertViewCustom.podspec ├── AlertViewCustom.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── FontExamples ├── AveriaSerifLibre-Bold.ttf └── AveriaSerifLibre-Regular.ttf ├── LICENSE ├── Package.swift ├── README.md ├── Sources └── AlertViewCustom │ ├── AlertView.swift │ ├── AlertViewCustom.swift │ └── Utils │ ├── Enums.swift │ ├── Extensions.swift │ └── Structs.swift ├── SwiftUIExamples ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── ContentView.swift ├── ContentViewModel.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json └── SwiftUIExamplesApp.swift └── UIKitExamples ├── AppDelegate.swift ├── Assets.xcassets ├── AccentColor.colorset │ └── Contents.json ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist └── ViewController.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | /Sources/CustomAlert/.DS_Store 92 | /.DS_Store 93 | .DS_Store 94 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: 2 | - trailing_whitespace 3 | 4 | analyzer_rules: 5 | - explicit_self 6 | 7 | included: 8 | - Sources -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AlertViewCustom.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'AlertViewCustom' 3 | s.version = '4.0.0' 4 | s.summary = 'Create a custom UIAlertView to fit the style of your app' 5 | 6 | s.description = <<-DESC 7 | With AlertViewCustom you can create your own customised UIAlertView instead of using the default one from Apple, which doesn't always fit in with the style of your app. 8 | DESC 9 | 10 | s.homepage = 'https://github.com/jadebowl/AlertViewCustom' 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | s.author = { 'Giada Ciotola' => 'giadaciotola@hotmail.it' } 13 | s.source = { :git => 'https://github.com/jadebowl/AlertViewCustom.git', :tag => s.version.to_s } 14 | 15 | s.ios.deployment_target = '14.0' 16 | s.source_files = 'Sources/**/*' 17 | s.frameworks = 'UIKit' 18 | 19 | s.swift_version = '5.0' 20 | 21 | end -------------------------------------------------------------------------------- /AlertViewCustom.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0E384B342ADFCC2A00FB4CCC /* ContentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E384B332ADFCC2A00FB4CCC /* ContentViewModel.swift */; }; 11 | 0E3920322AD9820E00EB5B78 /* AveriaSerifLibre-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0E39202C2AD9820E00EB5B78 /* AveriaSerifLibre-Bold.ttf */; }; 12 | 0E39203C2AD9820E00EB5B78 /* AveriaSerifLibre-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0E3920312AD9820E00EB5B78 /* AveriaSerifLibre-Regular.ttf */; }; 13 | 0E7A9DE72AD98EB000CB13AD /* Structs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7A9DE62AD98EB000CB13AD /* Structs.swift */; }; 14 | 0EA6AE152AC5DE9900C4E0FE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6AE142AC5DE9900C4E0FE /* AppDelegate.swift */; }; 15 | 0EA6AE192AC5DE9900C4E0FE /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6AE182AC5DE9900C4E0FE /* ViewController.swift */; }; 16 | 0EA6AE1C2AC5DE9900C4E0FE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0EA6AE1A2AC5DE9900C4E0FE /* Main.storyboard */; }; 17 | 0EA6AE1E2AC5DE9A00C4E0FE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0EA6AE1D2AC5DE9A00C4E0FE /* Assets.xcassets */; }; 18 | 0EA6AE212AC5DE9A00C4E0FE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0EA6AE1F2AC5DE9A00C4E0FE /* LaunchScreen.storyboard */; }; 19 | 0EA6AE2D2AC5DEC000C4E0FE /* SwiftUIExamplesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6AE2C2AC5DEC000C4E0FE /* SwiftUIExamplesApp.swift */; }; 20 | 0EA6AE2F2AC5DEC000C4E0FE /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6AE2E2AC5DEC000C4E0FE /* ContentView.swift */; }; 21 | 0EA6AE312AC5DEC100C4E0FE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0EA6AE302AC5DEC100C4E0FE /* Assets.xcassets */; }; 22 | 0EA6AE342AC5DEC100C4E0FE /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0EA6AE332AC5DEC100C4E0FE /* Preview Assets.xcassets */; }; 23 | 0EA6AE4F2AC5DF9C00C4E0FE /* AlertViewCustom.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EA6AE492AC5DF9C00C4E0FE /* AlertViewCustom.framework */; }; 24 | 0EA6AE502AC5DF9C00C4E0FE /* AlertViewCustom.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0EA6AE492AC5DF9C00C4E0FE /* AlertViewCustom.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 25 | 0EA6AE592AC5E07000C4E0FE /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6AE572AC5E07000C4E0FE /* Enums.swift */; }; 26 | 0EA6AE5A2AC5E07100C4E0FE /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6AE582AC5E07000C4E0FE /* Extensions.swift */; }; 27 | 0EA6AE5E2AC5E07900C4E0FE /* AlertViewCustom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6AE5C2AC5E07900C4E0FE /* AlertViewCustom.swift */; }; 28 | 0EA6AE612AC5E0F100C4E0FE /* AlertViewCustom.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EA6AE492AC5DF9C00C4E0FE /* AlertViewCustom.framework */; }; 29 | 0EA6AE622AC5E0F100C4E0FE /* AlertViewCustom.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0EA6AE492AC5DF9C00C4E0FE /* AlertViewCustom.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 30 | 7A980A6E2AC7661E00072821 /* AlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A980A6D2AC7661E00072821 /* AlertView.swift */; }; 31 | 8D3CA6542ADD87E5004BE429 /* AveriaSerifLibre-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0E39202C2AD9820E00EB5B78 /* AveriaSerifLibre-Bold.ttf */; }; 32 | 8D3CA6552ADD87E8004BE429 /* AveriaSerifLibre-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0E3920312AD9820E00EB5B78 /* AveriaSerifLibre-Regular.ttf */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 0EA6AE4D2AC5DF9C00C4E0FE /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 0EA6ADD32AC5DE1300C4E0FE /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 0EA6AE482AC5DF9C00C4E0FE; 41 | remoteInfo = CustomAlertView; 42 | }; 43 | 0EA6AE552AC5DFCB00C4E0FE /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = 0EA6ADD32AC5DE1300C4E0FE /* Project object */; 46 | proxyType = 1; 47 | remoteGlobalIDString = 0EA6AE482AC5DF9C00C4E0FE; 48 | remoteInfo = CustomAlertView; 49 | }; 50 | 0EA6AE632AC5E0F100C4E0FE /* PBXContainerItemProxy */ = { 51 | isa = PBXContainerItemProxy; 52 | containerPortal = 0EA6ADD32AC5DE1300C4E0FE /* Project object */; 53 | proxyType = 1; 54 | remoteGlobalIDString = 0EA6AE482AC5DF9C00C4E0FE; 55 | remoteInfo = CustomAlertView; 56 | }; 57 | /* End PBXContainerItemProxy section */ 58 | 59 | /* Begin PBXCopyFilesBuildPhase section */ 60 | 0EA6AE542AC5DF9C00C4E0FE /* Embed Frameworks */ = { 61 | isa = PBXCopyFilesBuildPhase; 62 | buildActionMask = 2147483647; 63 | dstPath = ""; 64 | dstSubfolderSpec = 10; 65 | files = ( 66 | 0EA6AE502AC5DF9C00C4E0FE /* AlertViewCustom.framework in Embed Frameworks */, 67 | ); 68 | name = "Embed Frameworks"; 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | 0EA6AE652AC5E0F100C4E0FE /* Embed Frameworks */ = { 72 | isa = PBXCopyFilesBuildPhase; 73 | buildActionMask = 2147483647; 74 | dstPath = ""; 75 | dstSubfolderSpec = 10; 76 | files = ( 77 | 0EA6AE622AC5E0F100C4E0FE /* AlertViewCustom.framework in Embed Frameworks */, 78 | ); 79 | name = "Embed Frameworks"; 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | /* End PBXCopyFilesBuildPhase section */ 83 | 84 | /* Begin PBXFileReference section */ 85 | 0E384B332ADFCC2A00FB4CCC /* ContentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewModel.swift; sourceTree = ""; }; 86 | 0E39202C2AD9820E00EB5B78 /* AveriaSerifLibre-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "AveriaSerifLibre-Bold.ttf"; sourceTree = ""; }; 87 | 0E3920312AD9820E00EB5B78 /* AveriaSerifLibre-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "AveriaSerifLibre-Regular.ttf"; sourceTree = ""; }; 88 | 0E7A9DE62AD98EB000CB13AD /* Structs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Structs.swift; sourceTree = ""; }; 89 | 0EA6AE122AC5DE9900C4E0FE /* UIKitExamples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UIKitExamples.app; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | 0EA6AE142AC5DE9900C4E0FE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 91 | 0EA6AE182AC5DE9900C4E0FE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 92 | 0EA6AE1B2AC5DE9900C4E0FE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 93 | 0EA6AE1D2AC5DE9A00C4E0FE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 94 | 0EA6AE202AC5DE9A00C4E0FE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 95 | 0EA6AE222AC5DE9A00C4E0FE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 96 | 0EA6AE2A2AC5DEC000C4E0FE /* SwiftUIExamples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUIExamples.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97 | 0EA6AE2C2AC5DEC000C4E0FE /* SwiftUIExamplesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIExamplesApp.swift; sourceTree = ""; }; 98 | 0EA6AE2E2AC5DEC000C4E0FE /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 99 | 0EA6AE302AC5DEC100C4E0FE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 100 | 0EA6AE332AC5DEC100C4E0FE /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 101 | 0EA6AE492AC5DF9C00C4E0FE /* AlertViewCustom.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AlertViewCustom.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 102 | 0EA6AE572AC5E07000C4E0FE /* Enums.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enums.swift; sourceTree = ""; }; 103 | 0EA6AE582AC5E07000C4E0FE /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 104 | 0EA6AE5C2AC5E07900C4E0FE /* AlertViewCustom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AlertViewCustom.swift; path = AlertViewCustom/AlertViewCustom.swift; sourceTree = ""; }; 105 | 7A980A6D2AC7661E00072821 /* AlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AlertView.swift; path = AlertViewCustom/AlertView.swift; sourceTree = ""; }; 106 | /* End PBXFileReference section */ 107 | 108 | /* Begin PBXFrameworksBuildPhase section */ 109 | 0EA6AE0F2AC5DE9900C4E0FE /* Frameworks */ = { 110 | isa = PBXFrameworksBuildPhase; 111 | buildActionMask = 2147483647; 112 | files = ( 113 | 0EA6AE4F2AC5DF9C00C4E0FE /* AlertViewCustom.framework in Frameworks */, 114 | ); 115 | runOnlyForDeploymentPostprocessing = 0; 116 | }; 117 | 0EA6AE272AC5DEC000C4E0FE /* Frameworks */ = { 118 | isa = PBXFrameworksBuildPhase; 119 | buildActionMask = 2147483647; 120 | files = ( 121 | 0EA6AE612AC5E0F100C4E0FE /* AlertViewCustom.framework in Frameworks */, 122 | ); 123 | runOnlyForDeploymentPostprocessing = 0; 124 | }; 125 | 0EA6AE462AC5DF9C00C4E0FE /* Frameworks */ = { 126 | isa = PBXFrameworksBuildPhase; 127 | buildActionMask = 2147483647; 128 | files = ( 129 | ); 130 | runOnlyForDeploymentPostprocessing = 0; 131 | }; 132 | /* End PBXFrameworksBuildPhase section */ 133 | 134 | /* Begin PBXGroup section */ 135 | 0E39202B2AD981E600EB5B78 /* FontExamples */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 0E3920312AD9820E00EB5B78 /* AveriaSerifLibre-Regular.ttf */, 139 | 0E39202C2AD9820E00EB5B78 /* AveriaSerifLibre-Bold.ttf */, 140 | ); 141 | path = FontExamples; 142 | sourceTree = ""; 143 | }; 144 | 0EA6ADD22AC5DE1300C4E0FE = { 145 | isa = PBXGroup; 146 | children = ( 147 | 0EA6AE4A2AC5DF9C00C4E0FE /* Sources */, 148 | 0EA6AE132AC5DE9900C4E0FE /* UIKitExamples */, 149 | 0EA6AE2B2AC5DEC000C4E0FE /* SwiftUIExamples */, 150 | 0E39202B2AD981E600EB5B78 /* FontExamples */, 151 | 0EA6ADDC2AC5DE1300C4E0FE /* Products */, 152 | 0EA6AE602AC5E0F100C4E0FE /* Frameworks */, 153 | ); 154 | sourceTree = ""; 155 | }; 156 | 0EA6ADDC2AC5DE1300C4E0FE /* Products */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 0EA6AE122AC5DE9900C4E0FE /* UIKitExamples.app */, 160 | 0EA6AE2A2AC5DEC000C4E0FE /* SwiftUIExamples.app */, 161 | 0EA6AE492AC5DF9C00C4E0FE /* AlertViewCustom.framework */, 162 | ); 163 | name = Products; 164 | sourceTree = ""; 165 | }; 166 | 0EA6AE132AC5DE9900C4E0FE /* UIKitExamples */ = { 167 | isa = PBXGroup; 168 | children = ( 169 | 0EA6AE142AC5DE9900C4E0FE /* AppDelegate.swift */, 170 | 0EA6AE182AC5DE9900C4E0FE /* ViewController.swift */, 171 | 0EA6AE1A2AC5DE9900C4E0FE /* Main.storyboard */, 172 | 0EA6AE1D2AC5DE9A00C4E0FE /* Assets.xcassets */, 173 | 0EA6AE1F2AC5DE9A00C4E0FE /* LaunchScreen.storyboard */, 174 | 0EA6AE222AC5DE9A00C4E0FE /* Info.plist */, 175 | ); 176 | path = UIKitExamples; 177 | sourceTree = ""; 178 | }; 179 | 0EA6AE2B2AC5DEC000C4E0FE /* SwiftUIExamples */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 0EA6AE2C2AC5DEC000C4E0FE /* SwiftUIExamplesApp.swift */, 183 | 0EA6AE2E2AC5DEC000C4E0FE /* ContentView.swift */, 184 | 0E384B332ADFCC2A00FB4CCC /* ContentViewModel.swift */, 185 | 0EA6AE302AC5DEC100C4E0FE /* Assets.xcassets */, 186 | 0EA6AE322AC5DEC100C4E0FE /* Preview Content */, 187 | ); 188 | path = SwiftUIExamples; 189 | sourceTree = ""; 190 | }; 191 | 0EA6AE322AC5DEC100C4E0FE /* Preview Content */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | 0EA6AE332AC5DEC100C4E0FE /* Preview Assets.xcassets */, 195 | ); 196 | path = "Preview Content"; 197 | sourceTree = ""; 198 | }; 199 | 0EA6AE4A2AC5DF9C00C4E0FE /* Sources */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 7A980A6D2AC7661E00072821 /* AlertView.swift */, 203 | 0EA6AE5C2AC5E07900C4E0FE /* AlertViewCustom.swift */, 204 | 7A980A712AC76BE800072821 /* Utils */, 205 | ); 206 | path = Sources; 207 | sourceTree = ""; 208 | }; 209 | 0EA6AE602AC5E0F100C4E0FE /* Frameworks */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | ); 213 | name = Frameworks; 214 | sourceTree = ""; 215 | }; 216 | 7A980A712AC76BE800072821 /* Utils */ = { 217 | isa = PBXGroup; 218 | children = ( 219 | 0E7A9DE62AD98EB000CB13AD /* Structs.swift */, 220 | 0EA6AE572AC5E07000C4E0FE /* Enums.swift */, 221 | 0EA6AE582AC5E07000C4E0FE /* Extensions.swift */, 222 | ); 223 | name = Utils; 224 | path = AlertViewCustom/Utils; 225 | sourceTree = ""; 226 | }; 227 | /* End PBXGroup section */ 228 | 229 | /* Begin PBXHeadersBuildPhase section */ 230 | 0EA6AE442AC5DF9C00C4E0FE /* Headers */ = { 231 | isa = PBXHeadersBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | /* End PBXHeadersBuildPhase section */ 238 | 239 | /* Begin PBXNativeTarget section */ 240 | 0EA6AE112AC5DE9900C4E0FE /* UIKitExamples */ = { 241 | isa = PBXNativeTarget; 242 | buildConfigurationList = 0EA6AE232AC5DE9A00C4E0FE /* Build configuration list for PBXNativeTarget "UIKitExamples" */; 243 | buildPhases = ( 244 | 0EA6AE0E2AC5DE9900C4E0FE /* Sources */, 245 | 0EA6AE0F2AC5DE9900C4E0FE /* Frameworks */, 246 | 0EA6AE102AC5DE9900C4E0FE /* Resources */, 247 | 0EA6AE542AC5DF9C00C4E0FE /* Embed Frameworks */, 248 | 8D3CA65B2ADDC871004BE429 /* SwiftLint */, 249 | ); 250 | buildRules = ( 251 | ); 252 | dependencies = ( 253 | 0EA6AE4E2AC5DF9C00C4E0FE /* PBXTargetDependency */, 254 | ); 255 | name = UIKitExamples; 256 | productName = UIKitExamples; 257 | productReference = 0EA6AE122AC5DE9900C4E0FE /* UIKitExamples.app */; 258 | productType = "com.apple.product-type.application"; 259 | }; 260 | 0EA6AE292AC5DEC000C4E0FE /* SwiftUIExamples */ = { 261 | isa = PBXNativeTarget; 262 | buildConfigurationList = 0EA6AE352AC5DEC100C4E0FE /* Build configuration list for PBXNativeTarget "SwiftUIExamples" */; 263 | buildPhases = ( 264 | 0EA6AE262AC5DEC000C4E0FE /* Sources */, 265 | 0EA6AE272AC5DEC000C4E0FE /* Frameworks */, 266 | 0EA6AE282AC5DEC000C4E0FE /* Resources */, 267 | 0EA6AE652AC5E0F100C4E0FE /* Embed Frameworks */, 268 | 8D3CA65C2ADDC9B8004BE429 /* SwiftLint */, 269 | ); 270 | buildRules = ( 271 | ); 272 | dependencies = ( 273 | 0EA6AE562AC5DFCB00C4E0FE /* PBXTargetDependency */, 274 | 0EA6AE642AC5E0F100C4E0FE /* PBXTargetDependency */, 275 | ); 276 | name = SwiftUIExamples; 277 | productName = SwiftUIExamples; 278 | productReference = 0EA6AE2A2AC5DEC000C4E0FE /* SwiftUIExamples.app */; 279 | productType = "com.apple.product-type.application"; 280 | }; 281 | 0EA6AE482AC5DF9C00C4E0FE /* AlertViewCustom */ = { 282 | isa = PBXNativeTarget; 283 | buildConfigurationList = 0EA6AE512AC5DF9C00C4E0FE /* Build configuration list for PBXNativeTarget "AlertViewCustom" */; 284 | buildPhases = ( 285 | 0EA6AE442AC5DF9C00C4E0FE /* Headers */, 286 | 0EA6AE452AC5DF9C00C4E0FE /* Sources */, 287 | 0EA6AE462AC5DF9C00C4E0FE /* Frameworks */, 288 | 0EA6AE472AC5DF9C00C4E0FE /* Resources */, 289 | ); 290 | buildRules = ( 291 | ); 292 | dependencies = ( 293 | ); 294 | name = AlertViewCustom; 295 | productName = CustomAlertView; 296 | productReference = 0EA6AE492AC5DF9C00C4E0FE /* AlertViewCustom.framework */; 297 | productType = "com.apple.product-type.framework"; 298 | }; 299 | /* End PBXNativeTarget section */ 300 | 301 | /* Begin PBXProject section */ 302 | 0EA6ADD32AC5DE1300C4E0FE /* Project object */ = { 303 | isa = PBXProject; 304 | attributes = { 305 | BuildIndependentTargetsInParallel = 1; 306 | LastSwiftUpdateCheck = 1500; 307 | LastUpgradeCheck = 1500; 308 | TargetAttributes = { 309 | 0EA6AE112AC5DE9900C4E0FE = { 310 | CreatedOnToolsVersion = 15.0; 311 | }; 312 | 0EA6AE292AC5DEC000C4E0FE = { 313 | CreatedOnToolsVersion = 15.0; 314 | }; 315 | 0EA6AE482AC5DF9C00C4E0FE = { 316 | CreatedOnToolsVersion = 15.0; 317 | LastSwiftMigration = 1500; 318 | }; 319 | }; 320 | }; 321 | buildConfigurationList = 0EA6ADD62AC5DE1300C4E0FE /* Build configuration list for PBXProject "AlertViewCustom" */; 322 | compatibilityVersion = "Xcode 14.0"; 323 | developmentRegion = en; 324 | hasScannedForEncodings = 0; 325 | knownRegions = ( 326 | en, 327 | Base, 328 | ); 329 | mainGroup = 0EA6ADD22AC5DE1300C4E0FE; 330 | productRefGroup = 0EA6ADDC2AC5DE1300C4E0FE /* Products */; 331 | projectDirPath = ""; 332 | projectRoot = ""; 333 | targets = ( 334 | 0EA6AE482AC5DF9C00C4E0FE /* AlertViewCustom */, 335 | 0EA6AE112AC5DE9900C4E0FE /* UIKitExamples */, 336 | 0EA6AE292AC5DEC000C4E0FE /* SwiftUIExamples */, 337 | ); 338 | }; 339 | /* End PBXProject section */ 340 | 341 | /* Begin PBXResourcesBuildPhase section */ 342 | 0EA6AE102AC5DE9900C4E0FE /* Resources */ = { 343 | isa = PBXResourcesBuildPhase; 344 | buildActionMask = 2147483647; 345 | files = ( 346 | 0E39203C2AD9820E00EB5B78 /* AveriaSerifLibre-Regular.ttf in Resources */, 347 | 0EA6AE212AC5DE9A00C4E0FE /* LaunchScreen.storyboard in Resources */, 348 | 0EA6AE1E2AC5DE9A00C4E0FE /* Assets.xcassets in Resources */, 349 | 0E3920322AD9820E00EB5B78 /* AveriaSerifLibre-Bold.ttf in Resources */, 350 | 0EA6AE1C2AC5DE9900C4E0FE /* Main.storyboard in Resources */, 351 | ); 352 | runOnlyForDeploymentPostprocessing = 0; 353 | }; 354 | 0EA6AE282AC5DEC000C4E0FE /* Resources */ = { 355 | isa = PBXResourcesBuildPhase; 356 | buildActionMask = 2147483647; 357 | files = ( 358 | 0EA6AE342AC5DEC100C4E0FE /* Preview Assets.xcassets in Resources */, 359 | 8D3CA6542ADD87E5004BE429 /* AveriaSerifLibre-Bold.ttf in Resources */, 360 | 8D3CA6552ADD87E8004BE429 /* AveriaSerifLibre-Regular.ttf in Resources */, 361 | 0EA6AE312AC5DEC100C4E0FE /* Assets.xcassets in Resources */, 362 | ); 363 | runOnlyForDeploymentPostprocessing = 0; 364 | }; 365 | 0EA6AE472AC5DF9C00C4E0FE /* Resources */ = { 366 | isa = PBXResourcesBuildPhase; 367 | buildActionMask = 2147483647; 368 | files = ( 369 | ); 370 | runOnlyForDeploymentPostprocessing = 0; 371 | }; 372 | /* End PBXResourcesBuildPhase section */ 373 | 374 | /* Begin PBXShellScriptBuildPhase section */ 375 | 8D3CA65B2ADDC871004BE429 /* SwiftLint */ = { 376 | isa = PBXShellScriptBuildPhase; 377 | alwaysOutOfDate = 1; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | ); 381 | inputFileListPaths = ( 382 | ); 383 | inputPaths = ( 384 | ); 385 | name = SwiftLint; 386 | outputFileListPaths = ( 387 | ); 388 | outputPaths = ( 389 | ); 390 | runOnlyForDeploymentPostprocessing = 0; 391 | shellPath = /bin/sh; 392 | shellScript = "if [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n\nif which swiftlint > /dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; 393 | }; 394 | 8D3CA65C2ADDC9B8004BE429 /* SwiftLint */ = { 395 | isa = PBXShellScriptBuildPhase; 396 | alwaysOutOfDate = 1; 397 | buildActionMask = 2147483647; 398 | files = ( 399 | ); 400 | inputFileListPaths = ( 401 | ); 402 | inputPaths = ( 403 | ); 404 | name = SwiftLint; 405 | outputFileListPaths = ( 406 | ); 407 | outputPaths = ( 408 | ); 409 | runOnlyForDeploymentPostprocessing = 0; 410 | shellPath = /bin/sh; 411 | shellScript = "if [[ \"$(uname -m)\" == arm64 ]]; then\n export PATH=\"/opt/homebrew/bin:$PATH\"\nfi\n\nif which swiftlint > /dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; 412 | }; 413 | /* End PBXShellScriptBuildPhase section */ 414 | 415 | /* Begin PBXSourcesBuildPhase section */ 416 | 0EA6AE0E2AC5DE9900C4E0FE /* Sources */ = { 417 | isa = PBXSourcesBuildPhase; 418 | buildActionMask = 2147483647; 419 | files = ( 420 | 0EA6AE192AC5DE9900C4E0FE /* ViewController.swift in Sources */, 421 | 0EA6AE152AC5DE9900C4E0FE /* AppDelegate.swift in Sources */, 422 | ); 423 | runOnlyForDeploymentPostprocessing = 0; 424 | }; 425 | 0EA6AE262AC5DEC000C4E0FE /* Sources */ = { 426 | isa = PBXSourcesBuildPhase; 427 | buildActionMask = 2147483647; 428 | files = ( 429 | 0EA6AE2F2AC5DEC000C4E0FE /* ContentView.swift in Sources */, 430 | 0EA6AE2D2AC5DEC000C4E0FE /* SwiftUIExamplesApp.swift in Sources */, 431 | 0E384B342ADFCC2A00FB4CCC /* ContentViewModel.swift in Sources */, 432 | ); 433 | runOnlyForDeploymentPostprocessing = 0; 434 | }; 435 | 0EA6AE452AC5DF9C00C4E0FE /* Sources */ = { 436 | isa = PBXSourcesBuildPhase; 437 | buildActionMask = 2147483647; 438 | files = ( 439 | 0E7A9DE72AD98EB000CB13AD /* Structs.swift in Sources */, 440 | 7A980A6E2AC7661E00072821 /* AlertView.swift in Sources */, 441 | 0EA6AE592AC5E07000C4E0FE /* Enums.swift in Sources */, 442 | 0EA6AE5A2AC5E07100C4E0FE /* Extensions.swift in Sources */, 443 | 0EA6AE5E2AC5E07900C4E0FE /* AlertViewCustom.swift in Sources */, 444 | ); 445 | runOnlyForDeploymentPostprocessing = 0; 446 | }; 447 | /* End PBXSourcesBuildPhase section */ 448 | 449 | /* Begin PBXTargetDependency section */ 450 | 0EA6AE4E2AC5DF9C00C4E0FE /* PBXTargetDependency */ = { 451 | isa = PBXTargetDependency; 452 | target = 0EA6AE482AC5DF9C00C4E0FE /* AlertViewCustom */; 453 | targetProxy = 0EA6AE4D2AC5DF9C00C4E0FE /* PBXContainerItemProxy */; 454 | }; 455 | 0EA6AE562AC5DFCB00C4E0FE /* PBXTargetDependency */ = { 456 | isa = PBXTargetDependency; 457 | target = 0EA6AE482AC5DF9C00C4E0FE /* AlertViewCustom */; 458 | targetProxy = 0EA6AE552AC5DFCB00C4E0FE /* PBXContainerItemProxy */; 459 | }; 460 | 0EA6AE642AC5E0F100C4E0FE /* PBXTargetDependency */ = { 461 | isa = PBXTargetDependency; 462 | target = 0EA6AE482AC5DF9C00C4E0FE /* AlertViewCustom */; 463 | targetProxy = 0EA6AE632AC5E0F100C4E0FE /* PBXContainerItemProxy */; 464 | }; 465 | /* End PBXTargetDependency section */ 466 | 467 | /* Begin PBXVariantGroup section */ 468 | 0EA6AE1A2AC5DE9900C4E0FE /* Main.storyboard */ = { 469 | isa = PBXVariantGroup; 470 | children = ( 471 | 0EA6AE1B2AC5DE9900C4E0FE /* Base */, 472 | ); 473 | name = Main.storyboard; 474 | sourceTree = ""; 475 | }; 476 | 0EA6AE1F2AC5DE9A00C4E0FE /* LaunchScreen.storyboard */ = { 477 | isa = PBXVariantGroup; 478 | children = ( 479 | 0EA6AE202AC5DE9A00C4E0FE /* Base */, 480 | ); 481 | name = LaunchScreen.storyboard; 482 | sourceTree = ""; 483 | }; 484 | /* End PBXVariantGroup section */ 485 | 486 | /* Begin XCBuildConfiguration section */ 487 | 0EA6ADED2AC5DE1400C4E0FE /* Debug */ = { 488 | isa = XCBuildConfiguration; 489 | buildSettings = { 490 | ALWAYS_SEARCH_USER_PATHS = NO; 491 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 492 | CLANG_ANALYZER_NONNULL = YES; 493 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 494 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 495 | CLANG_ENABLE_MODULES = YES; 496 | CLANG_ENABLE_OBJC_ARC = YES; 497 | CLANG_ENABLE_OBJC_WEAK = YES; 498 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 499 | CLANG_WARN_BOOL_CONVERSION = YES; 500 | CLANG_WARN_COMMA = YES; 501 | CLANG_WARN_CONSTANT_CONVERSION = YES; 502 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 503 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 504 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 505 | CLANG_WARN_EMPTY_BODY = YES; 506 | CLANG_WARN_ENUM_CONVERSION = YES; 507 | CLANG_WARN_INFINITE_RECURSION = YES; 508 | CLANG_WARN_INT_CONVERSION = YES; 509 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 510 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 511 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 512 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 513 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 514 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 515 | CLANG_WARN_STRICT_PROTOTYPES = YES; 516 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 517 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 518 | CLANG_WARN_UNREACHABLE_CODE = YES; 519 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 520 | COPY_PHASE_STRIP = NO; 521 | DEBUG_INFORMATION_FORMAT = dwarf; 522 | ENABLE_STRICT_OBJC_MSGSEND = YES; 523 | ENABLE_TESTABILITY = YES; 524 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 525 | GCC_C_LANGUAGE_STANDARD = gnu17; 526 | GCC_DYNAMIC_NO_PIC = NO; 527 | GCC_NO_COMMON_BLOCKS = YES; 528 | GCC_OPTIMIZATION_LEVEL = 0; 529 | GCC_PREPROCESSOR_DEFINITIONS = ( 530 | "DEBUG=1", 531 | "$(inherited)", 532 | ); 533 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 534 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 535 | GCC_WARN_UNDECLARED_SELECTOR = YES; 536 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 537 | GCC_WARN_UNUSED_FUNCTION = YES; 538 | GCC_WARN_UNUSED_VARIABLE = YES; 539 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 540 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 541 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 542 | MTL_FAST_MATH = YES; 543 | ONLY_ACTIVE_ARCH = YES; 544 | SDKROOT = iphoneos; 545 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 546 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 547 | SWIFT_VERSION = 5.0; 548 | }; 549 | name = Debug; 550 | }; 551 | 0EA6ADEE2AC5DE1400C4E0FE /* Release */ = { 552 | isa = XCBuildConfiguration; 553 | buildSettings = { 554 | ALWAYS_SEARCH_USER_PATHS = NO; 555 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 556 | CLANG_ANALYZER_NONNULL = YES; 557 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 558 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 559 | CLANG_ENABLE_MODULES = YES; 560 | CLANG_ENABLE_OBJC_ARC = YES; 561 | CLANG_ENABLE_OBJC_WEAK = YES; 562 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 563 | CLANG_WARN_BOOL_CONVERSION = YES; 564 | CLANG_WARN_COMMA = YES; 565 | CLANG_WARN_CONSTANT_CONVERSION = YES; 566 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 567 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 568 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 569 | CLANG_WARN_EMPTY_BODY = YES; 570 | CLANG_WARN_ENUM_CONVERSION = YES; 571 | CLANG_WARN_INFINITE_RECURSION = YES; 572 | CLANG_WARN_INT_CONVERSION = YES; 573 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 574 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 575 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 576 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 577 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 578 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 579 | CLANG_WARN_STRICT_PROTOTYPES = YES; 580 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 581 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 582 | CLANG_WARN_UNREACHABLE_CODE = YES; 583 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 584 | COPY_PHASE_STRIP = NO; 585 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 586 | ENABLE_NS_ASSERTIONS = NO; 587 | ENABLE_STRICT_OBJC_MSGSEND = YES; 588 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 589 | GCC_C_LANGUAGE_STANDARD = gnu17; 590 | GCC_NO_COMMON_BLOCKS = YES; 591 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 592 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 593 | GCC_WARN_UNDECLARED_SELECTOR = YES; 594 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 595 | GCC_WARN_UNUSED_FUNCTION = YES; 596 | GCC_WARN_UNUSED_VARIABLE = YES; 597 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 598 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 599 | MTL_ENABLE_DEBUG_INFO = NO; 600 | MTL_FAST_MATH = YES; 601 | SDKROOT = iphoneos; 602 | SWIFT_COMPILATION_MODE = wholemodule; 603 | SWIFT_VERSION = 5.0; 604 | VALIDATE_PRODUCT = YES; 605 | }; 606 | name = Release; 607 | }; 608 | 0EA6AE242AC5DE9A00C4E0FE /* Debug */ = { 609 | isa = XCBuildConfiguration; 610 | buildSettings = { 611 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 612 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 613 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 614 | CODE_SIGN_STYLE = Automatic; 615 | CURRENT_PROJECT_VERSION = 1; 616 | DEVELOPMENT_TEAM = 788S89FDTP; 617 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 618 | GENERATE_INFOPLIST_FILE = YES; 619 | INFOPLIST_FILE = UIKitExamples/Info.plist; 620 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 621 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 622 | INFOPLIST_KEY_UIMainStoryboardFile = Main; 623 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 624 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 625 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 626 | LD_RUNPATH_SEARCH_PATHS = ( 627 | "$(inherited)", 628 | "@executable_path/Frameworks", 629 | ); 630 | MARKETING_VERSION = 1.0.0; 631 | PRODUCT_BUNDLE_IDENTIFIER = com.jadegoescoding.AlertViewCustom.UIKitExamples; 632 | PRODUCT_NAME = "$(TARGET_NAME)"; 633 | SWIFT_EMIT_LOC_STRINGS = YES; 634 | SWIFT_VERSION = 5.0; 635 | TARGETED_DEVICE_FAMILY = "1,2"; 636 | }; 637 | name = Debug; 638 | }; 639 | 0EA6AE252AC5DE9A00C4E0FE /* Release */ = { 640 | isa = XCBuildConfiguration; 641 | buildSettings = { 642 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 643 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 644 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 645 | CODE_SIGN_STYLE = Automatic; 646 | CURRENT_PROJECT_VERSION = 1; 647 | DEVELOPMENT_TEAM = 788S89FDTP; 648 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 649 | GENERATE_INFOPLIST_FILE = YES; 650 | INFOPLIST_FILE = UIKitExamples/Info.plist; 651 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 652 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 653 | INFOPLIST_KEY_UIMainStoryboardFile = Main; 654 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 655 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 656 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 657 | LD_RUNPATH_SEARCH_PATHS = ( 658 | "$(inherited)", 659 | "@executable_path/Frameworks", 660 | ); 661 | MARKETING_VERSION = 1.0.0; 662 | PRODUCT_BUNDLE_IDENTIFIER = com.jadegoescoding.AlertViewCustom.UIKitExamples; 663 | PRODUCT_NAME = "$(TARGET_NAME)"; 664 | SWIFT_EMIT_LOC_STRINGS = YES; 665 | SWIFT_VERSION = 5.0; 666 | TARGETED_DEVICE_FAMILY = "1,2"; 667 | }; 668 | name = Release; 669 | }; 670 | 0EA6AE362AC5DEC100C4E0FE /* Debug */ = { 671 | isa = XCBuildConfiguration; 672 | buildSettings = { 673 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 674 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 675 | CODE_SIGN_STYLE = Automatic; 676 | CURRENT_PROJECT_VERSION = 1; 677 | DEVELOPMENT_ASSET_PATHS = "\"SwiftUIExamples/Preview Content\""; 678 | DEVELOPMENT_TEAM = 788S89FDTP; 679 | ENABLE_PREVIEWS = YES; 680 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 681 | GENERATE_INFOPLIST_FILE = YES; 682 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 683 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 684 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 685 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 686 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 687 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 688 | LD_RUNPATH_SEARCH_PATHS = ( 689 | "$(inherited)", 690 | "@executable_path/Frameworks", 691 | ); 692 | MARKETING_VERSION = 1.0.0; 693 | PRODUCT_BUNDLE_IDENTIFIER = com.jadegoescoding.AlertViewCustom.SwiftUIExamples; 694 | PRODUCT_NAME = "$(TARGET_NAME)"; 695 | SWIFT_EMIT_LOC_STRINGS = YES; 696 | SWIFT_VERSION = 5.0; 697 | TARGETED_DEVICE_FAMILY = "1,2"; 698 | }; 699 | name = Debug; 700 | }; 701 | 0EA6AE372AC5DEC100C4E0FE /* Release */ = { 702 | isa = XCBuildConfiguration; 703 | buildSettings = { 704 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 705 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 706 | CODE_SIGN_STYLE = Automatic; 707 | CURRENT_PROJECT_VERSION = 1; 708 | DEVELOPMENT_ASSET_PATHS = "\"SwiftUIExamples/Preview Content\""; 709 | DEVELOPMENT_TEAM = 788S89FDTP; 710 | ENABLE_PREVIEWS = YES; 711 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 712 | GENERATE_INFOPLIST_FILE = YES; 713 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 714 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 715 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 716 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 717 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 718 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 719 | LD_RUNPATH_SEARCH_PATHS = ( 720 | "$(inherited)", 721 | "@executable_path/Frameworks", 722 | ); 723 | MARKETING_VERSION = 1.0.0; 724 | PRODUCT_BUNDLE_IDENTIFIER = com.jadegoescoding.AlertViewCustom.SwiftUIExamples; 725 | PRODUCT_NAME = "$(TARGET_NAME)"; 726 | SWIFT_EMIT_LOC_STRINGS = YES; 727 | SWIFT_VERSION = 5.0; 728 | TARGETED_DEVICE_FAMILY = "1,2"; 729 | }; 730 | name = Release; 731 | }; 732 | 0EA6AE522AC5DF9C00C4E0FE /* Debug */ = { 733 | isa = XCBuildConfiguration; 734 | buildSettings = { 735 | CLANG_ENABLE_MODULES = YES; 736 | CODE_SIGN_STYLE = Automatic; 737 | CURRENT_PROJECT_VERSION = 1; 738 | DEFINES_MODULE = YES; 739 | DEVELOPMENT_TEAM = 788S89FDTP; 740 | DYLIB_COMPATIBILITY_VERSION = 1; 741 | DYLIB_CURRENT_VERSION = 1; 742 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 743 | ENABLE_MODULE_VERIFIER = YES; 744 | GENERATE_INFOPLIST_FILE = YES; 745 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 746 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 747 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 748 | LD_RUNPATH_SEARCH_PATHS = ( 749 | "$(inherited)", 750 | "@executable_path/Frameworks", 751 | "@loader_path/Frameworks", 752 | ); 753 | MARKETING_VERSION = 1.0.0; 754 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 755 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; 756 | PRODUCT_BUNDLE_IDENTIFIER = com.jadegoescoding.AlertViewCustom; 757 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 758 | SKIP_INSTALL = YES; 759 | SWIFT_EMIT_LOC_STRINGS = YES; 760 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 761 | SWIFT_VERSION = 5.0; 762 | TARGETED_DEVICE_FAMILY = "1,2"; 763 | TVOS_DEPLOYMENT_TARGET = 14.0; 764 | VERSIONING_SYSTEM = "apple-generic"; 765 | VERSION_INFO_PREFIX = ""; 766 | WATCHOS_DEPLOYMENT_TARGET = 7.0; 767 | }; 768 | name = Debug; 769 | }; 770 | 0EA6AE532AC5DF9C00C4E0FE /* Release */ = { 771 | isa = XCBuildConfiguration; 772 | buildSettings = { 773 | CLANG_ENABLE_MODULES = YES; 774 | CODE_SIGN_STYLE = Automatic; 775 | CURRENT_PROJECT_VERSION = 1; 776 | DEFINES_MODULE = YES; 777 | DEVELOPMENT_TEAM = 788S89FDTP; 778 | DYLIB_COMPATIBILITY_VERSION = 1; 779 | DYLIB_CURRENT_VERSION = 1; 780 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 781 | ENABLE_MODULE_VERIFIER = YES; 782 | GENERATE_INFOPLIST_FILE = YES; 783 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 784 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 785 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 786 | LD_RUNPATH_SEARCH_PATHS = ( 787 | "$(inherited)", 788 | "@executable_path/Frameworks", 789 | "@loader_path/Frameworks", 790 | ); 791 | MARKETING_VERSION = 1.0.0; 792 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 793 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; 794 | PRODUCT_BUNDLE_IDENTIFIER = com.jadegoescoding.AlertViewCustom; 795 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 796 | SKIP_INSTALL = YES; 797 | SWIFT_EMIT_LOC_STRINGS = YES; 798 | SWIFT_VERSION = 5.0; 799 | TARGETED_DEVICE_FAMILY = "1,2"; 800 | TVOS_DEPLOYMENT_TARGET = 14.0; 801 | VERSIONING_SYSTEM = "apple-generic"; 802 | VERSION_INFO_PREFIX = ""; 803 | WATCHOS_DEPLOYMENT_TARGET = 7.0; 804 | }; 805 | name = Release; 806 | }; 807 | /* End XCBuildConfiguration section */ 808 | 809 | /* Begin XCConfigurationList section */ 810 | 0EA6ADD62AC5DE1300C4E0FE /* Build configuration list for PBXProject "AlertViewCustom" */ = { 811 | isa = XCConfigurationList; 812 | buildConfigurations = ( 813 | 0EA6ADED2AC5DE1400C4E0FE /* Debug */, 814 | 0EA6ADEE2AC5DE1400C4E0FE /* Release */, 815 | ); 816 | defaultConfigurationIsVisible = 0; 817 | defaultConfigurationName = Release; 818 | }; 819 | 0EA6AE232AC5DE9A00C4E0FE /* Build configuration list for PBXNativeTarget "UIKitExamples" */ = { 820 | isa = XCConfigurationList; 821 | buildConfigurations = ( 822 | 0EA6AE242AC5DE9A00C4E0FE /* Debug */, 823 | 0EA6AE252AC5DE9A00C4E0FE /* Release */, 824 | ); 825 | defaultConfigurationIsVisible = 0; 826 | defaultConfigurationName = Release; 827 | }; 828 | 0EA6AE352AC5DEC100C4E0FE /* Build configuration list for PBXNativeTarget "SwiftUIExamples" */ = { 829 | isa = XCConfigurationList; 830 | buildConfigurations = ( 831 | 0EA6AE362AC5DEC100C4E0FE /* Debug */, 832 | 0EA6AE372AC5DEC100C4E0FE /* Release */, 833 | ); 834 | defaultConfigurationIsVisible = 0; 835 | defaultConfigurationName = Release; 836 | }; 837 | 0EA6AE512AC5DF9C00C4E0FE /* Build configuration list for PBXNativeTarget "AlertViewCustom" */ = { 838 | isa = XCConfigurationList; 839 | buildConfigurations = ( 840 | 0EA6AE522AC5DF9C00C4E0FE /* Debug */, 841 | 0EA6AE532AC5DF9C00C4E0FE /* Release */, 842 | ); 843 | defaultConfigurationIsVisible = 0; 844 | defaultConfigurationName = Release; 845 | }; 846 | /* End XCConfigurationList section */ 847 | }; 848 | rootObject = 0EA6ADD32AC5DE1300C4E0FE /* Project object */; 849 | } 850 | -------------------------------------------------------------------------------- /AlertViewCustom.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AlertViewCustom.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FontExamples/AveriaSerifLibre-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jadebowl/AlertViewCustom/4c7b521150f62cb0914b68a7d87acaf251d26089/FontExamples/AveriaSerifLibre-Bold.ttf -------------------------------------------------------------------------------- /FontExamples/AveriaSerifLibre-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jadebowl/AlertViewCustom/4c7b521150f62cb0914b68a7d87acaf251d26089/FontExamples/AveriaSerifLibre-Regular.ttf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Giada Ciotola 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.8 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "AlertViewCustom", 8 | platforms: [ 9 | .iOS(.v14), 10 | .macOS(.v11) 11 | ], 12 | products: [ 13 | .library( 14 | name: "AlertViewCustom", 15 | targets: ["AlertViewCustom"]), 16 | ], 17 | dependencies: [], 18 | targets: [ 19 | .target( 20 | name: "AlertViewCustom", 21 | dependencies: []) 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![SPM compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)]([https://swift.org/package-manager/](https://github.com/apple/swift-package-manager)) 2 | [![Version](https://img.shields.io/cocoapods/v/AlertViewCustom.svg?style=flat)](https://cocoapods.org/pods/AlertViewCustom) 3 | [![License](https://img.shields.io/cocoapods/l/AlertViewCustom.svg?style=flat)](https://cocoapods.org/pods/AlertViewCustom) 4 | 5 | 6 | [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fjadebowl%2FAlertViewCustom%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/jadebowl/AlertViewCustom) 7 | 8 | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/85d7d6bc1ccb4666ab9ef5b251b27621)](https://app.codacy.com/gh/jadebowl/AlertViewCustom/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) 9 | 10 | 11 | # AlertViewCustom 12 | 13 |

14 | With AlertViewCustom you can create your own customised UIAlertView instead of using the default one from Apple, which doesn't always fit in with the style of your app. 15 |

16 | 17 | ## Features 18 | - Can be used both in UIKit and SwiftUI 19 | - Add Icon 20 | - Personalise Title, Message and both Buttons 21 | - Possibility to hide Title, Message and Cancel Button 22 | - Change Alert Position (.center or .bottom) 23 | - Change Agree Button Corner Radius 24 | - Change Agree Button Color 25 | - Change View Background Color 26 | - Change Corner Radius of the whole AlertView 27 | - Add Animation from the Bottom when in .bottom Position 28 | 29 | ### Latest Updates: 30 | - Possibility to change Font 31 | - Possibility to have the Agree Button Outlined 32 | 33 | ## Examples 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 |
Bottom & No TitleFont CustomIcon & ColorOne Button
Position & No TitleFont CustomIcon & ColorOne Button
Outlined Button
Outlined Button & View Radius
60 | 61 | ## Installation 62 | 63 | ### Swift Package Manager 64 | 65 | To integrate using Apple's [Swift Package Manager](https://swift.org/package-manager/), add the following as a dependency to your `Package.swift`: 66 | 67 | ```swift 68 | dependencies: [ 69 | .package(url: "https://github.com/jadebowl/AlertViewCustom.git", from: "4.0.0") 70 | ] 71 | ``` 72 | 73 | Alternatively navigate to your Xcode project, select `Swift Packages` and click the `+` icon to search for `AlertViewCustom`. 74 | 75 | ### CocoaPods 76 | 77 | AlertViewCustom is available through [CocoaPods](http://cocoapods.org). To install 78 | it, simply add the following line to your Podfile: 79 | 80 | ```ruby 81 | pod 'AlertViewCustom' 82 | ``` 83 | 84 | ### Manually 85 | 86 | If you prefer not to use any of the aforementioned dependency managers, you can integrate AlertViewCustom into your project manually. Simply drag the `Sources` Folder into your Xcode project. 87 | 88 | ## Usage 89 | 90 | Create an Alert: 91 | ```swift 92 | import AlertViewCustom 93 | 94 | var alert = AlertView() 95 | ``` 96 | 97 | Customise the UI and add the Fade transition: 98 | ```swift 99 | let agreeButton = AgreeButton(title: "Go to Settings") 100 | let alertSettings = AlertSettings(accentColor: .systemBlue, 101 | backgroundColor: .systemBackground, 102 | icon: UIImage(systemName: "hand.wave"), 103 | title: "I am a title", 104 | message: "Lorem ipsum dolor sit amet, consectetuadipiscing elit, sed do eiusmod tempor incididunt ulabore et dolore magna aliqua.", 105 | agreeButton: agreeButton, 106 | cancelTitle: "Cancel", 107 | position: .bottom(animated: true)) 108 | alert.setupContents(delegate: self, settings: alertSettings) 109 | alert.fadeIn(duration: 0.3) 110 | ``` 111 | 112 | Manage Actions: 113 | ```swift 114 | extension Controller: AlertViewDelegate { 115 | func agreeAction() { 116 | // MARK: - Example: Go to Settings 117 | guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return } 118 | if UIApplication.shared.canOpenURL(settingsUrl) { 119 | UIApplication.shared.open(settingsUrl, completionHandler: { (success) in 120 | print("Settings opened: \(success)") 121 | }) 122 | } 123 | } 124 | 125 | func cancelAction() { 126 | alert.removeFromSuperView(duration: 0.3) 127 | } 128 | } 129 | ``` 130 | 131 | ## Contributing 132 | Contributions are very welcome 🙌 133 | -------------------------------------------------------------------------------- /Sources/AlertViewCustom/AlertView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | public protocol AlertViewDelegate: AnyObject { 4 | func agreeAction() 5 | func cancelAction() 6 | } 7 | 8 | /** 9 | With AlertViewCustom you can create your own customised UIAlertView instead of using the default one from Apple 10 | */ 11 | public class AlertView { 12 | public var delegate: AlertViewDelegate? { 13 | didSet { 14 | alertView.delegate = delegate 15 | } 16 | } 17 | private let alertView: AlertViewCustom 18 | private let hostVC: UIViewController 19 | private let alertWindow: UIWindow 20 | 21 | public init() { 22 | self.alertView = AlertViewCustom() 23 | self.alertWindow = UIWindow() 24 | self.alertWindow.backgroundColor = .clear 25 | 26 | let viewController = UIViewController() 27 | viewController.view.backgroundColor = .clear 28 | self.hostVC = viewController 29 | self.alertWindow.rootViewController = viewController 30 | } 31 | 32 | /** 33 | Setup the alert contents 34 | - parameters: 35 | - delegate: To manage the agree button and cancel button actions 36 | - settings: To customise your alert 37 | */ 38 | public func setupContents(delegate: AlertViewDelegate, settings: AlertSettings) { 39 | self.delegate = delegate 40 | setupContrastColor(accentColor: settings.accentColor, 41 | backgroundColor: settings.backgroundColor, 42 | borderWidth: settings.agreeButton.borderWidth) 43 | setupBackground(backgroundColor: settings.backgroundColor, backgroundRadius: settings.backgroundRadius) 44 | setupFont(fontName: settings.fontName) 45 | setupIcon(icon: settings.icon, accentColor: settings.accentColor) 46 | setupTitles(title: settings.title, message: settings.message) 47 | setupAgreeButton(accentColor: settings.accentColor, 48 | title: settings.agreeButton.title, 49 | cornerRadius: settings.agreeButton.cornerRadius, 50 | borderWidth: settings.agreeButton.borderWidth) 51 | setupCancelButton(accentColor: settings.accentColor, cancelTitle: settings.cancelTitle) 52 | setupPosition(position: settings.position) 53 | setupHostVCConstraints() 54 | } 55 | 56 | func setupContrastColor(accentColor: UIColor, backgroundColor: UIColor, borderWidth: CGFloat) { 57 | alertView.titleLabel.textColor = backgroundColor.contrastColor() 58 | alertView.messageLabel.textColor = backgroundColor.contrastColor() 59 | 60 | let titleColor = borderWidth != 0 ? accentColor : accentColor.contrastColor() 61 | alertView.agreeButton.setTitleColor(titleColor, for: .normal) 62 | } 63 | 64 | func setupBackground(backgroundColor: UIColor, backgroundRadius: CGFloat) { 65 | alertView.backgroundView.backgroundColor = backgroundColor 66 | alertView.backgroundView.layer.cornerRadius = backgroundRadius 67 | } 68 | 69 | func setupFont(fontName: String?) { 70 | guard fontName != nil, let fontName else { 71 | return 72 | } 73 | alertView.titleLabel.font = UIFont.font(for: .headline, name: fontName) 74 | alertView.messageLabel.font = UIFont.font(for: .body, name: fontName) 75 | alertView.agreeButton.titleLabel?.font = UIFont.font(for: .button, name: fontName) 76 | alertView.cancelButton.titleLabel?.font = UIFont.font(for: .body, name: fontName) 77 | } 78 | 79 | func setupIcon(icon: UIImage?, accentColor: UIColor) { 80 | alertView.iconImageView.image = icon 81 | alertView.iconImageView.tintColor = accentColor 82 | alertView.iconImageView.isHidden = alertView.iconImageView.image == nil 83 | } 84 | 85 | func setupTitles(title: String?, message: String?) { 86 | alertView.titleLabel.text = title 87 | alertView.titleLabel.isHidden = alertView.titleLabel.text == nil 88 | alertView.messageLabel.text = message 89 | alertView.messageLabel.isHidden = alertView.messageLabel.text == nil 90 | } 91 | 92 | func setupAgreeButton(accentColor: UIColor, title: String, cornerRadius: CGFloat, borderWidth: CGFloat) { 93 | alertView.agreeButton.setTitle(title, for: .normal) 94 | alertView.agreeButton.backgroundColor = borderWidth != 0 ? .clear : accentColor 95 | alertView.agreeButton.layer.borderColor = accentColor.cgColor 96 | alertView.agreeButton.layer.borderWidth = borderWidth 97 | alertView.agreeButton.layer.cornerRadius = cornerRadius 98 | } 99 | 100 | func setupCancelButton(accentColor: UIColor, cancelTitle: String?) { 101 | alertView.cancelButton.setTitle(cancelTitle, for: .normal) 102 | alertView.cancelButton.setTitleColor(accentColor, for: .normal) 103 | alertView.cancelButton.isHidden = cancelTitle == nil 104 | } 105 | 106 | func setupPosition(position: AlertPosition?) { 107 | guard let position else { return } 108 | switch position { 109 | case .bottom(let animation): 110 | alertView.alertBottomAnimation = animation 111 | alertView.backgroundView.translatesAutoresizingMaskIntoConstraints = false 112 | alertView.alertCenterConstraint?.isActive = false 113 | alertView.alertTopConstraint?.isActive = false 114 | alertView.alertBottomConstraint = alertView.backgroundView.bottomAnchor 115 | .constraint(equalTo: alertView.contentView.bottomAnchor, constant: -32) 116 | alertView.alertBottomConstraint?.isActive = true 117 | default: 118 | alertView.backgroundView.translatesAutoresizingMaskIntoConstraints = false 119 | alertView.alertBottomConstraint?.isActive = false 120 | 121 | alertView.backgroundView.centerXAnchor 122 | .constraint(equalTo: alertView.contentView.centerXAnchor).isActive = true 123 | alertView.backgroundView.centerYAnchor 124 | .constraint(equalTo: alertView.contentView.centerYAnchor).isActive = true 125 | alertView.backgroundView.widthAnchor.constraint(greaterThanOrEqualToConstant: 100).isActive = true 126 | alertView.backgroundView.heightAnchor.constraint(greaterThanOrEqualToConstant: 100).isActive = true 127 | 128 | alertView.alertCenterConstraint = alertView.backgroundView.centerYAnchor 129 | .constraint(equalTo: alertView.contentView.centerYAnchor) 130 | alertView.alertCenterConstraint?.isActive = true 131 | } 132 | } 133 | 134 | func setupHostVCConstraints() { 135 | hostVC.view.addSubview(alertView) 136 | alertView.translatesAutoresizingMaskIntoConstraints = false 137 | alertView.topAnchor.constraint(equalTo: hostVC.view.topAnchor, constant: 0).isActive = true 138 | alertView.bottomAnchor.constraint(equalTo: hostVC.view.bottomAnchor, constant: 0).isActive = true 139 | alertView.leadingAnchor.constraint(equalTo: hostVC.view.leadingAnchor, constant: 0).isActive = true 140 | alertView.trailingAnchor.constraint(equalTo: hostVC.view.trailingAnchor, constant: 0).isActive = true 141 | alertView.alpha = 0.0 142 | } 143 | 144 | /** 145 | Make the alert appear 146 | - parameters: 147 | - duration 148 | */ 149 | public func fadeIn(duration: TimeInterval) { 150 | if let activeScene = UIApplication.shared.activeWindowScene { 151 | alertWindow.windowScene = activeScene 152 | alertWindow.frame = activeScene.coordinateSpace.bounds 153 | } 154 | alertWindow.isHidden = false 155 | alertView.isHidden = false 156 | if alertView.alertBottomAnimation { 157 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { 158 | self.alertView.alertBottomConstraint?.constant = -96 159 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut) { 160 | self.alertView.contentView.layoutIfNeeded() 161 | self.alertView.alpha = 1 162 | } 163 | } 164 | } else { 165 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut) { 166 | self.alertView.alpha = 1 167 | } 168 | } 169 | } 170 | 171 | /** 172 | Make the alert disappear 173 | - parameters: 174 | - duration 175 | */ 176 | public func removeFromSuperView(duration: TimeInterval) { 177 | if alertView.alertBottomAnimation { 178 | alertView.alertBottomConstraint?.constant = -32 179 | } 180 | 181 | UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { 182 | self.alertView.alpha = 0.0 183 | if self.alertView.alertBottomAnimation { 184 | self.alertView.contentView.layoutIfNeeded() 185 | } 186 | }, completion: { completed in 187 | guard completed else { return } 188 | self.removeWindow() 189 | }) 190 | } 191 | 192 | private func removeWindow() { 193 | alertWindow.isHidden = true 194 | alertWindow.windowScene = nil 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /Sources/AlertViewCustom/AlertViewCustom.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class AlertViewCustom: UIView { 4 | lazy var contentView: UIView = { 5 | let view = UIView() 6 | view.backgroundColor = .clear 7 | return view 8 | }() 9 | 10 | lazy var blurredView: UIVisualEffectView = { 11 | let blurEffect = UIBlurEffect(style: .dark) 12 | let blurredEffectView = UIVisualEffectView(effect: blurEffect) 13 | return blurredEffectView 14 | }() 15 | 16 | lazy var backgroundView: UIView = { 17 | let view = UIView() 18 | return view 19 | }() 20 | 21 | lazy var mainStackView: UIStackView = { 22 | let stack = UIStackView() 23 | stack.axis = .vertical 24 | stack.alignment = .center 25 | stack.distribution = .fill 26 | stack.spacing = 24 27 | return stack 28 | }() 29 | 30 | lazy var iconImageView: UIImageView = { 31 | let image = UIImageView() 32 | return image 33 | }() 34 | 35 | lazy var titlesStackView: UIStackView = { 36 | let stack = UIStackView() 37 | stack.axis = .vertical 38 | stack.alignment = .fill 39 | stack.distribution = .fill 40 | stack.spacing = 12 41 | return stack 42 | }() 43 | 44 | lazy var titleLabel: UILabel = { 45 | let title = UILabel() 46 | title.numberOfLines = 0 47 | title.textAlignment = .center 48 | title.font = .preferredFont(forTextStyle: .headline) 49 | return title 50 | }() 51 | 52 | lazy var messageLabel: UILabel = { 53 | let title = UILabel() 54 | title.numberOfLines = 0 55 | title.textAlignment = .center 56 | title.font = .preferredFont(forTextStyle: .subheadline) 57 | return title 58 | }() 59 | 60 | lazy var buttonsStackView: UIStackView = { 61 | let stack = UIStackView() 62 | stack.axis = .vertical 63 | stack.alignment = .fill 64 | stack.distribution = .fill 65 | stack.spacing = 4 66 | return stack 67 | }() 68 | 69 | lazy var agreeButton: UIButton = { 70 | let button = UIButton() 71 | button.titleLabel?.font = .systemFont(ofSize: 17, weight: .semibold) 72 | return button 73 | }() 74 | 75 | lazy var cancelButton: UIButton = { 76 | let button = UIButton() 77 | button.titleLabel?.font = .systemFont(ofSize: 17, weight: .regular) 78 | return button 79 | }() 80 | 81 | weak var delegate: AlertViewDelegate? 82 | 83 | var alertCenterConstraint: NSLayoutConstraint? 84 | var alertTopConstraint: NSLayoutConstraint? 85 | var alertBottomConstraint: NSLayoutConstraint? 86 | var alertBottomAnimation = false 87 | 88 | func setupViews() { 89 | setupContentView() 90 | setupBlurredView() 91 | setupBackgroundView() 92 | setupMainStack() 93 | setupIcon() 94 | setupTitles() 95 | setupButtons() 96 | setupActions() 97 | } 98 | 99 | private func setupContentView() { 100 | addSubview(contentView) 101 | contentView.translatesAutoresizingMaskIntoConstraints = false 102 | contentView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true 103 | contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true 104 | contentView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true 105 | contentView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true 106 | } 107 | 108 | private func setupBlurredView() { 109 | contentView.addSubview(blurredView) 110 | blurredView.translatesAutoresizingMaskIntoConstraints = false 111 | blurredView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true 112 | blurredView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true 113 | blurredView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 0).isActive = true 114 | blurredView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0).isActive = true 115 | } 116 | 117 | private func setupBackgroundView() { 118 | contentView.addSubview(backgroundView) 119 | backgroundView.translatesAutoresizingMaskIntoConstraints = false 120 | backgroundView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 32).isActive = true 121 | backgroundView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true 122 | } 123 | 124 | private func setupMainStack() { 125 | backgroundView.addSubview(mainStackView) 126 | mainStackView.translatesAutoresizingMaskIntoConstraints = false 127 | mainStackView.topAnchor.constraint(equalTo: backgroundView.topAnchor, constant: 32).isActive = true 128 | mainStackView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor, constant: -16).isActive = true 129 | mainStackView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor, constant: 0).isActive = true 130 | mainStackView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor, constant: 0).isActive = true 131 | } 132 | 133 | private func setupIcon() { 134 | mainStackView.insertArrangedSubview(iconImageView, at: 0) 135 | iconImageView.contentMode = .scaleAspectFit 136 | iconImageView.translatesAutoresizingMaskIntoConstraints = false 137 | iconImageView.heightAnchor.constraint(equalToConstant: 40).isActive = true 138 | iconImageView.widthAnchor.constraint(equalToConstant: 40).isActive = true 139 | } 140 | 141 | private func setupTitles() { 142 | mainStackView.insertArrangedSubview(titlesStackView, at: 1) 143 | titlesStackView.translatesAutoresizingMaskIntoConstraints = false 144 | titlesStackView.insertArrangedSubview(titleLabel, at: 0) 145 | titlesStackView.insertArrangedSubview(messageLabel, at: 1) 146 | titlesStackView.leadingAnchor.constraint(equalTo: mainStackView.leadingAnchor, constant: 16).isActive = true 147 | } 148 | 149 | private func setupButtons() { 150 | mainStackView.insertArrangedSubview(buttonsStackView, at: 2) 151 | buttonsStackView.insertArrangedSubview(agreeButton, at: 0) 152 | buttonsStackView.insertArrangedSubview(cancelButton, at: 1) 153 | buttonsStackView.translatesAutoresizingMaskIntoConstraints = false 154 | buttonsStackView.leadingAnchor.constraint(equalTo: mainStackView.leadingAnchor, constant: 16).isActive = true 155 | agreeButton.translatesAutoresizingMaskIntoConstraints = false 156 | agreeButton.heightAnchor.constraint(equalToConstant: 56).isActive = true 157 | cancelButton.translatesAutoresizingMaskIntoConstraints = false 158 | cancelButton.heightAnchor.constraint(equalToConstant: 56).isActive = true 159 | } 160 | 161 | private func setupActions() { 162 | agreeButton.addTarget(self, action: #selector(agreeAction), for: .touchUpInside) 163 | cancelButton.addTarget(self, action: #selector(cancelAction), for: .touchUpInside) 164 | } 165 | 166 | @objc private func agreeAction(_ sender: UIButton) { 167 | delegate?.agreeAction() 168 | } 169 | 170 | @objc private func cancelAction(_ sender: UIButton) { 171 | delegate?.cancelAction() 172 | } 173 | 174 | override init(frame: CGRect) { 175 | super.init(frame: frame) 176 | setupViews() 177 | } 178 | 179 | required init?(coder aDecoder: NSCoder) { 180 | super.init(coder: aDecoder) 181 | setupViews() 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /Sources/AlertViewCustom/Utils/Enums.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | /// Choose the alert position 4 | public enum AlertPosition { 5 | /// Default position 6 | case center 7 | /// When set to true the alert appears with an animation from the bottom 8 | case bottom(animated: Bool) 9 | } 10 | -------------------------------------------------------------------------------- /Sources/AlertViewCustom/Utils/Extensions.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | internal extension UIColor { 4 | func contrastColor() -> UIColor { 5 | var bit = CGFloat(0) 6 | var red = CGFloat(0) 7 | var green = CGFloat(0) 8 | var blue = CGFloat(0) 9 | var alpha = CGFloat(0) 10 | 11 | getRed(&red, green: &green, blue: &blue, alpha: &alpha) 12 | 13 | let luminance = 1 - ((0.299 * red) + (0.587 * green) + (0.114 * blue)) 14 | if luminance < 0.5 { 15 | bit = CGFloat(0) 16 | } else { 17 | bit = CGFloat(1) 18 | } 19 | return UIColor(red: bit, green: bit, blue: bit, alpha: 1) 20 | } 21 | } 22 | 23 | extension UIWindow { 24 | func dismiss() { 25 | isHidden = true 26 | windowScene = nil 27 | } 28 | } 29 | 30 | internal extension UIApplication { 31 | var activeWindowScene: UIWindowScene? { 32 | return connectedScenes 33 | .compactMap { $0 as? UIWindowScene } 34 | .first { $0.activationState == .foregroundActive } 35 | } 36 | } 37 | 38 | internal extension UIFont { 39 | enum FontStyle { 40 | case headline 41 | case body 42 | case button 43 | 44 | var metrics: UIFontMetrics? { 45 | switch self { 46 | case .headline: return UIFontMetrics(forTextStyle: .headline) 47 | case .body: return UIFontMetrics(forTextStyle: .body) 48 | case .button: return UIFontMetrics(forTextStyle: .body) 49 | } 50 | } 51 | 52 | var size: CGFloat { 53 | switch self { 54 | case .headline: return 19 55 | case .body: return 17 56 | case .button: return 19 57 | } 58 | } 59 | 60 | func fontName(name: String) -> String { 61 | switch self { 62 | case .headline, .button: return name+"-Bold" 63 | case .body: return name+"-Regular" 64 | } 65 | } 66 | } 67 | 68 | static func font(for style: FontStyle, name: String) -> UIFont { 69 | let font = UIFont(name: style.fontName(name: name), size: style.size) ?? UIFont.systemFont(ofSize: style.size) 70 | return style.metrics?.scaledFont(for: font) ?? font 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Sources/AlertViewCustom/Utils/Structs.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | /** 4 | All the alert properties you can customise 5 | - parameters: 6 | - accentColor: Applies color to icon, agree button background and cancel button title 7 | - backgroundColor 8 | - backgroundRadius: Applies a corner radius to the alert view 9 | - fontName: Applies a custom font to title, message, agree button and cancel button. 10 | Font files imported in the project folder have to be named with suffixes "-Regular" and "-Bold" 11 | - icon 12 | - title 13 | - message 14 | - agreeButton: With a title, a corner radius and a border width 15 | - cancelTitle 16 | - position 17 | */ 18 | public struct AlertSettings { 19 | public init(accentColor: UIColor, 20 | backgroundColor: UIColor, 21 | backgroundRadius: CGFloat = 16, 22 | fontName: String? = nil, 23 | icon: UIImage? = nil, 24 | title: String? = nil, 25 | message: String? = nil, 26 | agreeButton: AgreeButton, 27 | cancelTitle: String? = nil, 28 | position: AlertPosition? = .center) { 29 | self.accentColor = accentColor 30 | self.backgroundColor = backgroundColor 31 | self.backgroundRadius = backgroundRadius 32 | self.fontName = fontName 33 | self.icon = icon 34 | self.title = title 35 | self.message = message 36 | self.agreeButton = agreeButton 37 | self.cancelTitle = cancelTitle 38 | self.position = position 39 | } 40 | let accentColor: UIColor 41 | let backgroundColor: UIColor 42 | let backgroundRadius: CGFloat 43 | let fontName: String? 44 | let icon: UIImage? 45 | let title: String? 46 | let message: String? 47 | let agreeButton: AgreeButton 48 | let cancelTitle: String? 49 | let position: AlertPosition? 50 | } 51 | 52 | /** 53 | Customise the agree button 54 | - parameters: 55 | - title 56 | - cornerRadius 57 | - borderWidth: Applies a border with the accentColor and makes the background clear 58 | */ 59 | public struct AgreeButton { 60 | public init(title: String, cornerRadius: CGFloat = 16, borderWidth: CGFloat = 0) { 61 | self.title = title 62 | self.cornerRadius = cornerRadius 63 | self.borderWidth = borderWidth 64 | } 65 | let title: String 66 | let cornerRadius: CGFloat 67 | let borderWidth: CGFloat 68 | } 69 | -------------------------------------------------------------------------------- /SwiftUIExamples/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SwiftUIExamples/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /SwiftUIExamples/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUIExamples/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // SwiftUIExamples 4 | // 5 | // Created by Giada Ciotola on 28/09/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | @StateObject var viewModel = ContentViewModel() 12 | 13 | var body: some View { 14 | Color.blue 15 | .ignoresSafeArea(.all) 16 | .overlay( 17 | VStack { 18 | Button { 19 | viewModel.showAlert() 20 | } label: { 21 | Text("Show Alert") 22 | }.font(.system(size: 17, weight: .semibold, design: .default)) 23 | .foregroundColor(.white) 24 | }) 25 | } 26 | } 27 | 28 | #Preview { 29 | ContentView() 30 | } 31 | -------------------------------------------------------------------------------- /SwiftUIExamples/ContentViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentViewModel.swift 3 | // SwiftUIExamples 4 | // 5 | // Created by Giada Ciotola on 18/10/23. 6 | // 7 | 8 | import SwiftUI 9 | import AlertViewCustom 10 | 11 | class ContentViewModel: ObservableObject { 12 | let alert = AlertView() 13 | 14 | func showAlert() { 15 | let agreeButton = AgreeButton(title: "Go to Settings") 16 | let alertSettings = AlertSettings(accentColor: .systemBlue, 17 | backgroundColor: .systemBackground, 18 | icon: UIImage(systemName: "hand.wave"), 19 | title: "I am a title", 20 | message: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", 21 | agreeButton: agreeButton, 22 | cancelTitle: "Cancel", 23 | position: .center) 24 | alert.setupContents(delegate: self, settings: alertSettings) 25 | alert.fadeIn(duration: 0.3) 26 | } 27 | } 28 | 29 | extension ContentViewModel: AlertViewDelegate { 30 | func agreeAction() { 31 | // MARK: - Example: Go to Settings 32 | guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return } 33 | if UIApplication.shared.canOpenURL(settingsUrl) { 34 | UIApplication.shared.open(settingsUrl, completionHandler: { (success) in 35 | print("Settings opened: \(success)") 36 | }) 37 | } 38 | } 39 | 40 | func cancelAction() { 41 | alert.removeFromSuperView(duration: 0.3) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SwiftUIExamples/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUIExamples/SwiftUIExamplesApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUIExamplesApp.swift 3 | // SwiftUIExamples 4 | // 5 | // Created by Giada Ciotola on 28/09/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct SwiftUIExamplesApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /UIKitExamples/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // UIKitExamples 4 | // 5 | // Created by Giada Ciotola on 28/09/23. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | var window: UIWindow? 13 | 14 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 15 | return true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /UIKitExamples/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /UIKitExamples/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /UIKitExamples/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /UIKitExamples/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 | -------------------------------------------------------------------------------- /UIKitExamples/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /UIKitExamples/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIAppFonts 6 | 7 | AveriaSerifLibre-Regular.ttf 8 | AveriaSerifLibre-Bold.ttf 9 | AveriaSerifLibre-Italic.ttf 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /UIKitExamples/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // UIKitExamples 4 | // 5 | // Created by Giada Ciotola on 28/09/23. 6 | // 7 | 8 | import UIKit 9 | import AlertViewCustom 10 | 11 | class ViewController: UIViewController { 12 | 13 | var alert = AlertView() 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | } 18 | 19 | func setupAlert() { 20 | let agreeButton = AgreeButton(title: "Go to Settings", borderWidth: 3) 21 | let alertSettings = AlertSettings(accentColor: .systemBlue, 22 | backgroundColor: .systemBackground, 23 | fontName: "AveriaSerifLibre", 24 | icon: UIImage(systemName: "hand.wave"), 25 | title: "I am a title", 26 | message: "Lorem ipsum dolor sit amet, consectetuadipiscing elit, sed do eiusmod tempor incididunt ulabore et dolore magna aliqua.", 27 | agreeButton: agreeButton, 28 | cancelTitle: "Cancel", 29 | position: .bottom(animated: true)) 30 | alert.setupContents(delegate: self, settings: alertSettings) 31 | alert.fadeIn(duration: 0.3) 32 | } 33 | 34 | @IBAction func showAlert(_ sender: UIButton) { 35 | setupAlert() 36 | } 37 | } 38 | 39 | extension ViewController: AlertViewDelegate { 40 | func agreeAction() { 41 | // MARK: - Example: Go to Settings 42 | guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return } 43 | if UIApplication.shared.canOpenURL(settingsUrl) { 44 | UIApplication.shared.open(settingsUrl, completionHandler: { (success) in 45 | print("Settings opened: \(success)") 46 | }) 47 | } 48 | } 49 | 50 | func cancelAction() { 51 | alert.removeFromSuperView(duration: 0.3) 52 | } 53 | } 54 | --------------------------------------------------------------------------------