├── .gitignore ├── CustomIOSAlertView.podspec ├── CustomIOSAlertView ├── CustomIOSAlertView.xcodeproj │ └── project.pbxproj └── CustomIOSAlertView │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ └── Main_iPhone.storyboard │ ├── CustomIOSAlertView-Info.plist │ ├── CustomIOSAlertView-Prefix.pch │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── gplay-research-icon120.png │ │ ├── gplay-research-icon152.png │ │ └── gplay-research-icon76.png │ ├── Contents.json │ └── LaunchImage.launchimage │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 6p.png │ │ ├── Contents.json │ │ ├── h.png │ │ └── l.png │ ├── Resources │ └── demo.png │ ├── View │ ├── CustomIOSAlertView.h │ └── CustomIOSAlertView.m │ ├── ViewController.h │ ├── ViewController.m │ ├── en.lproj │ └── InfoPlist.strings │ └── main.m ├── Docs └── screen.png ├── LICENSE.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Exclude temp nibs and swap files 2 | *~.nib 3 | *.swp 4 | 5 | # Exclude user-specific XCode 3 and 4 files 6 | *.mode1 7 | *.mode1v3 8 | *.mode2v3 9 | *.perspective 10 | *.perspectivev3 11 | *.pbxuser 12 | *.xcworkspace 13 | xcuserdata 14 | -------------------------------------------------------------------------------- /CustomIOSAlertView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "CustomIOSAlertView" 4 | s.version = "0.9.5" 5 | s.summary = "Custom UIAlertView. Continue adding images and UIViews to dialogs on iOS7+." 6 | 7 | s.description = <<-DESC 8 | The addSubview is not available in UIAlertView in iOS7+. The view hierarchy for this 9 | class is private and must not be modified. As a solution, this class creates an iOS-style dialog which 10 | you can extend with any UIViews or buttons. The animations and the looks are copied too and no images 11 | or other resources are needed. 12 | DESC 13 | 14 | s.homepage = "https://github.com/wimagguc/ios-custom-alertview" 15 | s.screenshots = "https://github.com/wimagguc/ios-custom-alertview/raw/master/Docs/screen.png" 16 | 17 | s.license = { :type => "MIT", :file => "LICENSE.md" } 18 | 19 | s.author = { "Richard Dancsi" => "wimagguc@gmail.com" } 20 | s.social_media_url = "http://twitter.com/wimagguc" 21 | 22 | s.platform = :ios 23 | 24 | s.source = { :git => "https://github.com/wimagguc/ios-custom-alertview.git", :tag => "0.9.5" } 25 | 26 | s.source_files = "CustomIOSAlertView/CustomIOSAlertView/View/**/*.{h,m}" 27 | 28 | s.requires_arc = true 29 | 30 | end 31 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5EB26CCB17EC5EEB00F0971C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EB26CCA17EC5EEB00F0971C /* Foundation.framework */; }; 11 | 5EB26CCD17EC5EEB00F0971C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EB26CCC17EC5EEB00F0971C /* CoreGraphics.framework */; }; 12 | 5EB26CCF17EC5EEB00F0971C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EB26CCE17EC5EEB00F0971C /* UIKit.framework */; }; 13 | 5EB26CD517EC5EEB00F0971C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5EB26CD317EC5EEB00F0971C /* InfoPlist.strings */; }; 14 | 5EB26CD717EC5EEB00F0971C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB26CD617EC5EEB00F0971C /* main.m */; }; 15 | 5EB26CDB17EC5EEB00F0971C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB26CDA17EC5EEB00F0971C /* AppDelegate.m */; }; 16 | 5EB26CDE17EC5EEB00F0971C /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EB26CDC17EC5EEB00F0971C /* Main_iPhone.storyboard */; }; 17 | 5EB26CE417EC5EEB00F0971C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB26CE317EC5EEB00F0971C /* ViewController.m */; }; 18 | 5EB26D0317EC642000F0971C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5EB26D0217EC642000F0971C /* Images.xcassets */; }; 19 | 5EE9A9BB17EC68960031B75E /* CustomIOSAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE9A9BA17EC68960031B75E /* CustomIOSAlertView.m */; }; 20 | 5EE9A9BE17EC7EA60031B75E /* demo.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EE9A9BD17EC7EA60031B75E /* demo.png */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | 5EB26CC717EC5EEA00F0971C /* CustomIOSAlertView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CustomIOSAlertView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 5EB26CCA17EC5EEB00F0971C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 26 | 5EB26CCC17EC5EEB00F0971C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 27 | 5EB26CCE17EC5EEB00F0971C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 28 | 5EB26CD217EC5EEB00F0971C /* CustomIOSAlertView-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CustomIOSAlertView-Info.plist"; sourceTree = ""; }; 29 | 5EB26CD417EC5EEB00F0971C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 30 | 5EB26CD617EC5EEB00F0971C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 31 | 5EB26CD817EC5EEB00F0971C /* CustomIOSAlertView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CustomIOSAlertView-Prefix.pch"; sourceTree = ""; }; 32 | 5EB26CD917EC5EEB00F0971C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 33 | 5EB26CDA17EC5EEB00F0971C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 34 | 5EB26CDD17EC5EEB00F0971C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; 35 | 5EB26CE217EC5EEB00F0971C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 36 | 5EB26CE317EC5EEB00F0971C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 37 | 5EB26D0217EC642000F0971C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 38 | 5EE9A9B917EC68960031B75E /* CustomIOSAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomIOSAlertView.h; sourceTree = ""; }; 39 | 5EE9A9BA17EC68960031B75E /* CustomIOSAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomIOSAlertView.m; sourceTree = ""; }; 40 | 5EE9A9BD17EC7EA60031B75E /* demo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = demo.png; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 5EB26CC417EC5EEA00F0971C /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 5EB26CCD17EC5EEB00F0971C /* CoreGraphics.framework in Frameworks */, 49 | 5EB26CCF17EC5EEB00F0971C /* UIKit.framework in Frameworks */, 50 | 5EB26CCB17EC5EEB00F0971C /* Foundation.framework in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | 5EB26CBE17EC5EEA00F0971C = { 58 | isa = PBXGroup; 59 | children = ( 60 | 5EB26CD017EC5EEB00F0971C /* CustomIOSAlertView */, 61 | 5EB26CC917EC5EEA00F0971C /* Frameworks */, 62 | 5EB26CC817EC5EEA00F0971C /* Products */, 63 | ); 64 | sourceTree = ""; 65 | }; 66 | 5EB26CC817EC5EEA00F0971C /* Products */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 5EB26CC717EC5EEA00F0971C /* CustomIOSAlertView.app */, 70 | ); 71 | name = Products; 72 | sourceTree = ""; 73 | }; 74 | 5EB26CC917EC5EEA00F0971C /* Frameworks */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 5EB26CCA17EC5EEB00F0971C /* Foundation.framework */, 78 | 5EB26CCC17EC5EEB00F0971C /* CoreGraphics.framework */, 79 | 5EB26CCE17EC5EEB00F0971C /* UIKit.framework */, 80 | ); 81 | name = Frameworks; 82 | sourceTree = ""; 83 | }; 84 | 5EB26CD017EC5EEB00F0971C /* CustomIOSAlertView */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 5EE9A9B817EC68650031B75E /* View */, 88 | 5EB26CD917EC5EEB00F0971C /* AppDelegate.h */, 89 | 5EB26CDA17EC5EEB00F0971C /* AppDelegate.m */, 90 | 5EB26CE217EC5EEB00F0971C /* ViewController.h */, 91 | 5EB26CE317EC5EEB00F0971C /* ViewController.m */, 92 | 5EB26D0217EC642000F0971C /* Images.xcassets */, 93 | 5EB26CD117EC5EEB00F0971C /* Supporting Files */, 94 | ); 95 | path = CustomIOSAlertView; 96 | sourceTree = ""; 97 | }; 98 | 5EB26CD117EC5EEB00F0971C /* Supporting Files */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 5EE9A9BC17EC7EA00031B75E /* Resources */, 102 | 5EB26CDC17EC5EEB00F0971C /* Main_iPhone.storyboard */, 103 | 5EB26CD217EC5EEB00F0971C /* CustomIOSAlertView-Info.plist */, 104 | 5EB26CD317EC5EEB00F0971C /* InfoPlist.strings */, 105 | 5EB26CD617EC5EEB00F0971C /* main.m */, 106 | 5EB26CD817EC5EEB00F0971C /* CustomIOSAlertView-Prefix.pch */, 107 | ); 108 | name = "Supporting Files"; 109 | sourceTree = ""; 110 | }; 111 | 5EE9A9B817EC68650031B75E /* View */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 5EE9A9B917EC68960031B75E /* CustomIOSAlertView.h */, 115 | 5EE9A9BA17EC68960031B75E /* CustomIOSAlertView.m */, 116 | ); 117 | path = View; 118 | sourceTree = ""; 119 | }; 120 | 5EE9A9BC17EC7EA00031B75E /* Resources */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 5EE9A9BD17EC7EA60031B75E /* demo.png */, 124 | ); 125 | path = Resources; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | 5EB26CC617EC5EEA00F0971C /* CustomIOSAlertView */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = 5EB26CFC17EC5EEB00F0971C /* Build configuration list for PBXNativeTarget "CustomIOSAlertView" */; 134 | buildPhases = ( 135 | 5EB26CC317EC5EEA00F0971C /* Sources */, 136 | 5EB26CC417EC5EEA00F0971C /* Frameworks */, 137 | 5EB26CC517EC5EEA00F0971C /* Resources */, 138 | ); 139 | buildRules = ( 140 | ); 141 | dependencies = ( 142 | ); 143 | name = CustomIOSAlertView; 144 | productName = CustomIOSAlertView; 145 | productReference = 5EB26CC717EC5EEA00F0971C /* CustomIOSAlertView.app */; 146 | productType = "com.apple.product-type.application"; 147 | }; 148 | /* End PBXNativeTarget section */ 149 | 150 | /* Begin PBXProject section */ 151 | 5EB26CBF17EC5EEA00F0971C /* Project object */ = { 152 | isa = PBXProject; 153 | attributes = { 154 | LastUpgradeCheck = 0710; 155 | ORGANIZATIONNAME = Wimagguc; 156 | }; 157 | buildConfigurationList = 5EB26CC217EC5EEA00F0971C /* Build configuration list for PBXProject "CustomIOSAlertView" */; 158 | compatibilityVersion = "Xcode 3.2"; 159 | developmentRegion = English; 160 | hasScannedForEncodings = 0; 161 | knownRegions = ( 162 | en, 163 | Base, 164 | ); 165 | mainGroup = 5EB26CBE17EC5EEA00F0971C; 166 | productRefGroup = 5EB26CC817EC5EEA00F0971C /* Products */; 167 | projectDirPath = ""; 168 | projectRoot = ""; 169 | targets = ( 170 | 5EB26CC617EC5EEA00F0971C /* CustomIOSAlertView */, 171 | ); 172 | }; 173 | /* End PBXProject section */ 174 | 175 | /* Begin PBXResourcesBuildPhase section */ 176 | 5EB26CC517EC5EEA00F0971C /* Resources */ = { 177 | isa = PBXResourcesBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | 5EE9A9BE17EC7EA60031B75E /* demo.png in Resources */, 181 | 5EB26D0317EC642000F0971C /* Images.xcassets in Resources */, 182 | 5EB26CDE17EC5EEB00F0971C /* Main_iPhone.storyboard in Resources */, 183 | 5EB26CD517EC5EEB00F0971C /* InfoPlist.strings in Resources */, 184 | ); 185 | runOnlyForDeploymentPostprocessing = 0; 186 | }; 187 | /* End PBXResourcesBuildPhase section */ 188 | 189 | /* Begin PBXSourcesBuildPhase section */ 190 | 5EB26CC317EC5EEA00F0971C /* Sources */ = { 191 | isa = PBXSourcesBuildPhase; 192 | buildActionMask = 2147483647; 193 | files = ( 194 | 5EE9A9BB17EC68960031B75E /* CustomIOSAlertView.m in Sources */, 195 | 5EB26CE417EC5EEB00F0971C /* ViewController.m in Sources */, 196 | 5EB26CDB17EC5EEB00F0971C /* AppDelegate.m in Sources */, 197 | 5EB26CD717EC5EEB00F0971C /* main.m in Sources */, 198 | ); 199 | runOnlyForDeploymentPostprocessing = 0; 200 | }; 201 | /* End PBXSourcesBuildPhase section */ 202 | 203 | /* Begin PBXVariantGroup section */ 204 | 5EB26CD317EC5EEB00F0971C /* InfoPlist.strings */ = { 205 | isa = PBXVariantGroup; 206 | children = ( 207 | 5EB26CD417EC5EEB00F0971C /* en */, 208 | ); 209 | name = InfoPlist.strings; 210 | sourceTree = ""; 211 | }; 212 | 5EB26CDC17EC5EEB00F0971C /* Main_iPhone.storyboard */ = { 213 | isa = PBXVariantGroup; 214 | children = ( 215 | 5EB26CDD17EC5EEB00F0971C /* Base */, 216 | ); 217 | name = Main_iPhone.storyboard; 218 | sourceTree = ""; 219 | }; 220 | /* End PBXVariantGroup section */ 221 | 222 | /* Begin XCBuildConfiguration section */ 223 | 5EB26CFA17EC5EEB00F0971C /* Debug */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | ALWAYS_SEARCH_USER_PATHS = NO; 227 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 228 | CLANG_CXX_LIBRARY = "libc++"; 229 | CLANG_ENABLE_MODULES = YES; 230 | CLANG_ENABLE_OBJC_ARC = YES; 231 | CLANG_WARN_BOOL_CONVERSION = YES; 232 | CLANG_WARN_CONSTANT_CONVERSION = YES; 233 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 234 | CLANG_WARN_EMPTY_BODY = YES; 235 | CLANG_WARN_ENUM_CONVERSION = YES; 236 | CLANG_WARN_INT_CONVERSION = YES; 237 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 238 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 239 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 240 | COPY_PHASE_STRIP = NO; 241 | ENABLE_TESTABILITY = YES; 242 | GCC_C_LANGUAGE_STANDARD = gnu99; 243 | GCC_DYNAMIC_NO_PIC = NO; 244 | GCC_OPTIMIZATION_LEVEL = 0; 245 | GCC_PREPROCESSOR_DEFINITIONS = ( 246 | "DEBUG=1", 247 | "$(inherited)", 248 | ); 249 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 250 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 251 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 252 | GCC_WARN_UNDECLARED_SELECTOR = YES; 253 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 254 | GCC_WARN_UNUSED_FUNCTION = YES; 255 | GCC_WARN_UNUSED_VARIABLE = YES; 256 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 257 | ONLY_ACTIVE_ARCH = YES; 258 | SDKROOT = iphoneos; 259 | TARGETED_DEVICE_FAMILY = "1,2"; 260 | }; 261 | name = Debug; 262 | }; 263 | 5EB26CFB17EC5EEB00F0971C /* Release */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = NO; 267 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 268 | CLANG_CXX_LIBRARY = "libc++"; 269 | CLANG_ENABLE_MODULES = YES; 270 | CLANG_ENABLE_OBJC_ARC = YES; 271 | CLANG_WARN_BOOL_CONVERSION = YES; 272 | CLANG_WARN_CONSTANT_CONVERSION = YES; 273 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 274 | CLANG_WARN_EMPTY_BODY = YES; 275 | CLANG_WARN_ENUM_CONVERSION = YES; 276 | CLANG_WARN_INT_CONVERSION = YES; 277 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 278 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 279 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 280 | COPY_PHASE_STRIP = YES; 281 | ENABLE_NS_ASSERTIONS = NO; 282 | GCC_C_LANGUAGE_STANDARD = gnu99; 283 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 284 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 285 | GCC_WARN_UNDECLARED_SELECTOR = YES; 286 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 287 | GCC_WARN_UNUSED_FUNCTION = YES; 288 | GCC_WARN_UNUSED_VARIABLE = YES; 289 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 290 | SDKROOT = iphoneos; 291 | TARGETED_DEVICE_FAMILY = "1,2"; 292 | VALIDATE_PRODUCT = YES; 293 | }; 294 | name = Release; 295 | }; 296 | 5EB26CFD17EC5EEB00F0971C /* Debug */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 300 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 301 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 302 | GCC_PREFIX_HEADER = "CustomIOSAlertView/CustomIOSAlertView-Prefix.pch"; 303 | INFOPLIST_FILE = "CustomIOSAlertView/CustomIOSAlertView-Info.plist"; 304 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 305 | PRODUCT_BUNDLE_IDENTIFIER = "com.example.$(PRODUCT_NAME:rfc1034identifier)"; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | WRAPPER_EXTENSION = app; 308 | }; 309 | name = Debug; 310 | }; 311 | 5EB26CFE17EC5EEB00F0971C /* Release */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 315 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 316 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 317 | GCC_PREFIX_HEADER = "CustomIOSAlertView/CustomIOSAlertView-Prefix.pch"; 318 | INFOPLIST_FILE = "CustomIOSAlertView/CustomIOSAlertView-Info.plist"; 319 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 320 | PRODUCT_BUNDLE_IDENTIFIER = "com.example.$(PRODUCT_NAME:rfc1034identifier)"; 321 | PRODUCT_NAME = "$(TARGET_NAME)"; 322 | WRAPPER_EXTENSION = app; 323 | }; 324 | name = Release; 325 | }; 326 | /* End XCBuildConfiguration section */ 327 | 328 | /* Begin XCConfigurationList section */ 329 | 5EB26CC217EC5EEA00F0971C /* Build configuration list for PBXProject "CustomIOSAlertView" */ = { 330 | isa = XCConfigurationList; 331 | buildConfigurations = ( 332 | 5EB26CFA17EC5EEB00F0971C /* Debug */, 333 | 5EB26CFB17EC5EEB00F0971C /* Release */, 334 | ); 335 | defaultConfigurationIsVisible = 0; 336 | defaultConfigurationName = Release; 337 | }; 338 | 5EB26CFC17EC5EEB00F0971C /* Build configuration list for PBXNativeTarget "CustomIOSAlertView" */ = { 339 | isa = XCConfigurationList; 340 | buildConfigurations = ( 341 | 5EB26CFD17EC5EEB00F0971C /* Debug */, 342 | 5EB26CFE17EC5EEB00F0971C /* Release */, 343 | ); 344 | defaultConfigurationIsVisible = 0; 345 | defaultConfigurationName = Release; 346 | }; 347 | /* End XCConfigurationList section */ 348 | }; 349 | rootObject = 5EB26CBF17EC5EEA00F0971C /* Project object */; 350 | } 351 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CustomIOSAlertView 4 | // 5 | // Created by Richard on 20/09/2013. 6 | // Copyright (c) 2013-2015 Wimagguc. 7 | // 8 | // Lincesed under The MIT License (MIT) 9 | // http://opensource.org/licenses/MIT 10 | // 11 | 12 | #import 13 | 14 | @interface AppDelegate : UIResponder 15 | 16 | @property (strong, nonatomic) UIWindow *window; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CustomIOSAlertView 4 | // 5 | // Created by Richard on 20/09/2013. 6 | // Copyright (c) 2013-2015 Wimagguc. 7 | // 8 | // Lincesed under The MIT License (MIT) 9 | // http://opensource.org/licenses/MIT 10 | // 11 | 12 | #import "AppDelegate.h" 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | // Override point for customization after application launch. 19 | return YES; 20 | } 21 | 22 | - (void)applicationWillResignActive:(UIApplication *)application 23 | { 24 | // 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. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application 29 | { 30 | // 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. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | - (void)applicationWillEnterForeground:(UIApplication *)application 35 | { 36 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 37 | } 38 | 39 | - (void)applicationDidBecomeActive:(UIApplication *)application 40 | { 41 | // 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. 42 | } 43 | 44 | - (void)applicationWillTerminate:(UIApplication *)application 45 | { 46 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Base.lproj/Main_iPhone.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 | 27 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/CustomIOSAlertView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0.1 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0.1 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main_iPhone 29 | UIMainStoryboardFile~ipad 30 | Main_iPhone 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | UIInterfaceOrientationPortraitUpsideDown 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/CustomIOSAlertView-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "gplay-research-icon120.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "idiom" : "iphone", 31 | "size" : "60x60", 32 | "scale" : "3x" 33 | }, 34 | { 35 | "idiom" : "ipad", 36 | "size" : "29x29", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "idiom" : "ipad", 41 | "size" : "29x29", 42 | "scale" : "2x" 43 | }, 44 | { 45 | "idiom" : "ipad", 46 | "size" : "40x40", 47 | "scale" : "1x" 48 | }, 49 | { 50 | "idiom" : "ipad", 51 | "size" : "40x40", 52 | "scale" : "2x" 53 | }, 54 | { 55 | "size" : "76x76", 56 | "idiom" : "ipad", 57 | "filename" : "gplay-research-icon76.png", 58 | "scale" : "1x" 59 | }, 60 | { 61 | "size" : "76x76", 62 | "idiom" : "ipad", 63 | "filename" : "gplay-research-icon152.png", 64 | "scale" : "2x" 65 | } 66 | ], 67 | "info" : { 68 | "version" : 1, 69 | "author" : "xcode" 70 | } 71 | } -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/AppIcon.appiconset/gplay-research-icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/AppIcon.appiconset/gplay-research-icon120.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/AppIcon.appiconset/gplay-research-icon152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/AppIcon.appiconset/gplay-research-icon152.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/AppIcon.appiconset/gplay-research-icon76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/AppIcon.appiconset/gplay-research-icon76.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/4.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/5.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/6.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/6p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/6p.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "736h", 7 | "filename" : "6p.png", 8 | "minimum-system-version" : "8.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "orientation" : "landscape", 14 | "idiom" : "iphone", 15 | "extent" : "full-screen", 16 | "minimum-system-version" : "8.0", 17 | "subtype" : "736h", 18 | "scale" : "3x" 19 | }, 20 | { 21 | "extent" : "full-screen", 22 | "idiom" : "iphone", 23 | "subtype" : "667h", 24 | "filename" : "6.png", 25 | "minimum-system-version" : "8.0", 26 | "orientation" : "portrait", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "orientation" : "portrait", 31 | "idiom" : "iphone", 32 | "filename" : "4.png", 33 | "extent" : "full-screen", 34 | "minimum-system-version" : "7.0", 35 | "scale" : "2x" 36 | }, 37 | { 38 | "extent" : "full-screen", 39 | "idiom" : "iphone", 40 | "subtype" : "retina4", 41 | "filename" : "5.png", 42 | "minimum-system-version" : "7.0", 43 | "orientation" : "portrait", 44 | "scale" : "2x" 45 | }, 46 | { 47 | "orientation" : "portrait", 48 | "idiom" : "ipad", 49 | "filename" : "l.png", 50 | "extent" : "full-screen", 51 | "minimum-system-version" : "7.0", 52 | "scale" : "1x" 53 | }, 54 | { 55 | "orientation" : "landscape", 56 | "idiom" : "ipad", 57 | "extent" : "full-screen", 58 | "minimum-system-version" : "7.0", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "orientation" : "portrait", 63 | "idiom" : "ipad", 64 | "filename" : "h.png", 65 | "extent" : "full-screen", 66 | "minimum-system-version" : "7.0", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "orientation" : "landscape", 71 | "idiom" : "ipad", 72 | "extent" : "full-screen", 73 | "minimum-system-version" : "7.0", 74 | "scale" : "2x" 75 | }, 76 | { 77 | "orientation" : "portrait", 78 | "idiom" : "iphone", 79 | "extent" : "full-screen", 80 | "scale" : "1x" 81 | }, 82 | { 83 | "orientation" : "portrait", 84 | "idiom" : "iphone", 85 | "extent" : "full-screen", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "orientation" : "portrait", 90 | "idiom" : "iphone", 91 | "extent" : "full-screen", 92 | "subtype" : "retina4", 93 | "scale" : "2x" 94 | }, 95 | { 96 | "orientation" : "portrait", 97 | "idiom" : "ipad", 98 | "extent" : "to-status-bar", 99 | "scale" : "1x" 100 | }, 101 | { 102 | "orientation" : "portrait", 103 | "idiom" : "ipad", 104 | "extent" : "full-screen", 105 | "scale" : "1x" 106 | }, 107 | { 108 | "orientation" : "landscape", 109 | "idiom" : "ipad", 110 | "extent" : "to-status-bar", 111 | "scale" : "1x" 112 | }, 113 | { 114 | "orientation" : "landscape", 115 | "idiom" : "ipad", 116 | "extent" : "full-screen", 117 | "scale" : "1x" 118 | }, 119 | { 120 | "orientation" : "portrait", 121 | "idiom" : "ipad", 122 | "extent" : "to-status-bar", 123 | "scale" : "2x" 124 | }, 125 | { 126 | "orientation" : "portrait", 127 | "idiom" : "ipad", 128 | "extent" : "full-screen", 129 | "scale" : "2x" 130 | }, 131 | { 132 | "orientation" : "landscape", 133 | "idiom" : "ipad", 134 | "extent" : "to-status-bar", 135 | "scale" : "2x" 136 | }, 137 | { 138 | "orientation" : "landscape", 139 | "idiom" : "ipad", 140 | "extent" : "full-screen", 141 | "scale" : "2x" 142 | } 143 | ], 144 | "info" : { 145 | "version" : 1, 146 | "author" : "xcode" 147 | } 148 | } -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/h.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/l.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Images.xcassets/LaunchImage.launchimage/l.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/Resources/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/CustomIOSAlertView/CustomIOSAlertView/Resources/demo.png -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/View/CustomIOSAlertView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomIOSAlertView.h 3 | // CustomIOSAlertView 4 | // 5 | // Created by Richard on 20/09/2013. 6 | // Copyright (c) 2013-2015 Wimagguc. 7 | // 8 | // Lincesed under The MIT License (MIT) 9 | // http://opensource.org/licenses/MIT 10 | // 11 | 12 | #import 13 | 14 | @protocol CustomIOSAlertViewDelegate 15 | 16 | - (void)customIOS7dialogButtonTouchUpInside:(id)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; 17 | 18 | @end 19 | 20 | @interface CustomIOSAlertView : UIView 21 | 22 | @property (nonatomic, retain) UIView *parentView; // The parent view this 'dialog' is attached to 23 | @property (nonatomic, retain) UIView *dialogView; // Dialog's container view 24 | @property (nonatomic, retain) UIView *containerView; // Container within the dialog (place your ui elements here) 25 | 26 | @property (nonatomic, assign) id delegate; 27 | @property (nonatomic, retain) NSArray *buttonTitles; 28 | @property (nonatomic, assign) BOOL useMotionEffects; 29 | @property (nonatomic, assign) BOOL closeOnTouchUpOutside; // Closes the AlertView when finger is lifted outside the bounds. 30 | 31 | @property (copy) void (^onButtonTouchUpInside)(CustomIOSAlertView *alertView, int buttonIndex) ; 32 | 33 | - (id)init; 34 | 35 | /*! 36 | DEPRECATED: Use the [CustomIOSAlertView init] method without passing a parent view. 37 | */ 38 | - (id)initWithParentView: (UIView *)_parentView __attribute__ ((deprecated)); 39 | 40 | - (void)show; 41 | - (void)close; 42 | 43 | - (IBAction)customIOS7dialogButtonTouchUpInside:(id)sender; 44 | - (void)setOnButtonTouchUpInside:(void (^)(CustomIOSAlertView *alertView, int buttonIndex))onButtonTouchUpInside; 45 | 46 | - (void)deviceOrientationDidChange: (NSNotification *)notification; 47 | - (void)dealloc; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/View/CustomIOSAlertView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomIOSAlertView.m 3 | // CustomIOSAlertView 4 | // 5 | // Created by Richard on 20/09/2013. 6 | // Copyright (c) 2013-2015 Wimagguc. 7 | // 8 | // Lincesed under The MIT License (MIT) 9 | // http://opensource.org/licenses/MIT 10 | // 11 | 12 | #import "CustomIOSAlertView.h" 13 | #import 14 | 15 | const static CGFloat kCustomIOSAlertViewDefaultButtonHeight = 50; 16 | const static CGFloat kCustomIOSAlertViewDefaultButtonSpacerHeight = 1; 17 | const static CGFloat kCustomIOSAlertViewCornerRadius = 7; 18 | const static CGFloat kCustomIOS7MotionEffectExtent = 10.0; 19 | 20 | @implementation CustomIOSAlertView 21 | 22 | CGFloat buttonHeight = 0; 23 | CGFloat buttonSpacerHeight = 0; 24 | 25 | @synthesize parentView, containerView, dialogView, onButtonTouchUpInside; 26 | @synthesize delegate; 27 | @synthesize buttonTitles; 28 | @synthesize useMotionEffects; 29 | @synthesize closeOnTouchUpOutside; 30 | 31 | - (id)initWithParentView: (UIView *)_parentView 32 | { 33 | self = [self init]; 34 | if (_parentView) { 35 | self.frame = _parentView.frame; 36 | self.parentView = _parentView; 37 | } 38 | return self; 39 | } 40 | 41 | - (id)init 42 | { 43 | self = [super init]; 44 | if (self) { 45 | self.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); 46 | 47 | delegate = self; 48 | useMotionEffects = false; 49 | closeOnTouchUpOutside = false; 50 | buttonTitles = @[@"Close"]; 51 | 52 | [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 53 | 54 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; 55 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 56 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 57 | } 58 | return self; 59 | } 60 | 61 | // Create the dialog view, and animate opening the dialog 62 | - (void)show 63 | { 64 | dialogView = [self createContainerView]; 65 | 66 | dialogView.layer.shouldRasterize = YES; 67 | dialogView.layer.rasterizationScale = [[UIScreen mainScreen] scale]; 68 | 69 | self.layer.shouldRasterize = YES; 70 | self.layer.rasterizationScale = [[UIScreen mainScreen] scale]; 71 | 72 | #if (defined(__IPHONE_7_0)) 73 | if (useMotionEffects) { 74 | [self applyMotionEffects]; 75 | } 76 | #endif 77 | 78 | self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0]; 79 | 80 | [self addSubview:dialogView]; 81 | 82 | // Can be attached to a view or to the top most window 83 | // Attached to a view: 84 | if (parentView != NULL) { 85 | [parentView addSubview:self]; 86 | 87 | // Attached to the top most window 88 | } else { 89 | 90 | // On iOS7, calculate with orientation 91 | if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { 92 | 93 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 94 | switch (interfaceOrientation) { 95 | case UIInterfaceOrientationLandscapeLeft: 96 | self.transform = CGAffineTransformMakeRotation(M_PI * 270.0 / 180.0); 97 | break; 98 | 99 | case UIInterfaceOrientationLandscapeRight: 100 | self.transform = CGAffineTransformMakeRotation(M_PI * 90.0 / 180.0); 101 | break; 102 | 103 | case UIInterfaceOrientationPortraitUpsideDown: 104 | self.transform = CGAffineTransformMakeRotation(M_PI * 180.0 / 180.0); 105 | break; 106 | 107 | default: 108 | break; 109 | } 110 | 111 | [self setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 112 | 113 | // On iOS8, just place the dialog in the middle 114 | } else { 115 | 116 | CGSize screenSize = [self countScreenSize]; 117 | CGSize dialogSize = [self countDialogSize]; 118 | CGSize keyboardSize = CGSizeMake(0, 0); 119 | 120 | dialogView.frame = CGRectMake((screenSize.width - dialogSize.width) / 2, (screenSize.height - keyboardSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height); 121 | 122 | } 123 | 124 | [[[[UIApplication sharedApplication] windows] firstObject] addSubview:self]; 125 | } 126 | 127 | dialogView.layer.opacity = 0.5f; 128 | dialogView.layer.transform = CATransform3DMakeScale(1.3f, 1.3f, 1.0); 129 | 130 | [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionCurveEaseInOut 131 | animations:^{ 132 | self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4f]; 133 | dialogView.layer.opacity = 1.0f; 134 | dialogView.layer.transform = CATransform3DMakeScale(1, 1, 1); 135 | } 136 | completion:NULL 137 | ]; 138 | 139 | } 140 | 141 | // Button has been touched 142 | - (IBAction)customIOS7dialogButtonTouchUpInside:(id)sender 143 | { 144 | if (delegate != NULL) { 145 | [delegate customIOS7dialogButtonTouchUpInside:self clickedButtonAtIndex:[sender tag]]; 146 | } 147 | 148 | if (onButtonTouchUpInside != NULL) { 149 | onButtonTouchUpInside(self, (int)[sender tag]); 150 | } 151 | } 152 | 153 | // Default button behaviour 154 | - (void)customIOS7dialogButtonTouchUpInside: (CustomIOSAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 155 | { 156 | NSLog(@"Button Clicked! %d, %d", (int)buttonIndex, (int)[alertView tag]); 157 | [self close]; 158 | } 159 | 160 | // Dialog close animation then cleaning and removing the view from the parent 161 | - (void)close 162 | { 163 | CATransform3D currentTransform = dialogView.layer.transform; 164 | 165 | if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { 166 | CGFloat startRotation = [[dialogView valueForKeyPath:@"layer.transform.rotation.z"] floatValue]; 167 | CATransform3D rotation = CATransform3DMakeRotation(-startRotation + M_PI * 270.0 / 180.0, 0.0f, 0.0f, 0.0f); 168 | 169 | dialogView.layer.transform = CATransform3DConcat(rotation, CATransform3DMakeScale(1, 1, 1)); 170 | } 171 | 172 | dialogView.layer.opacity = 1.0f; 173 | 174 | [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone 175 | animations:^{ 176 | self.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.0f]; 177 | dialogView.layer.transform = CATransform3DConcat(currentTransform, CATransform3DMakeScale(0.6f, 0.6f, 1.0)); 178 | dialogView.layer.opacity = 0.0f; 179 | } 180 | completion:^(BOOL finished) { 181 | for (UIView *v in [self subviews]) { 182 | [v removeFromSuperview]; 183 | } 184 | [self removeFromSuperview]; 185 | } 186 | ]; 187 | } 188 | 189 | - (void)setSubView: (UIView *)subView 190 | { 191 | containerView = subView; 192 | } 193 | 194 | // Creates the container view here: create the dialog, then add the custom content and buttons 195 | - (UIView *)createContainerView 196 | { 197 | if (containerView == NULL) { 198 | containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 150)]; 199 | } 200 | 201 | CGSize screenSize = [self countScreenSize]; 202 | CGSize dialogSize = [self countDialogSize]; 203 | 204 | // For the black background 205 | [self setFrame:CGRectMake(0, 0, screenSize.width, screenSize.height)]; 206 | 207 | // This is the dialog's container; we attach the custom content and the buttons to this one 208 | UIView *dialogContainer = [[UIView alloc] initWithFrame:CGRectMake((screenSize.width - dialogSize.width) / 2, (screenSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height)]; 209 | 210 | // First, we style the dialog to match the iOS7 UIAlertView >>> 211 | CAGradientLayer *gradient = [CAGradientLayer layer]; 212 | gradient.frame = dialogContainer.bounds; 213 | gradient.colors = [NSArray arrayWithObjects: 214 | (id)[[UIColor colorWithRed:218.0/255.0 green:218.0/255.0 blue:218.0/255.0 alpha:1.0f] CGColor], 215 | (id)[[UIColor colorWithRed:233.0/255.0 green:233.0/255.0 blue:233.0/255.0 alpha:1.0f] CGColor], 216 | (id)[[UIColor colorWithRed:218.0/255.0 green:218.0/255.0 blue:218.0/255.0 alpha:1.0f] CGColor], 217 | nil]; 218 | 219 | CGFloat cornerRadius = kCustomIOSAlertViewCornerRadius; 220 | gradient.cornerRadius = cornerRadius; 221 | [dialogContainer.layer insertSublayer:gradient atIndex:0]; 222 | 223 | dialogContainer.layer.cornerRadius = cornerRadius; 224 | dialogContainer.layer.borderColor = [[UIColor colorWithRed:198.0/255.0 green:198.0/255.0 blue:198.0/255.0 alpha:1.0f] CGColor]; 225 | dialogContainer.layer.borderWidth = 1; 226 | dialogContainer.layer.shadowRadius = cornerRadius + 5; 227 | dialogContainer.layer.shadowOpacity = 0.1f; 228 | dialogContainer.layer.shadowOffset = CGSizeMake(0 - (cornerRadius+5)/2, 0 - (cornerRadius+5)/2); 229 | dialogContainer.layer.shadowColor = [UIColor blackColor].CGColor; 230 | dialogContainer.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:dialogContainer.bounds cornerRadius:dialogContainer.layer.cornerRadius].CGPath; 231 | 232 | // There is a line above the button 233 | UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, dialogContainer.bounds.size.height - buttonHeight - buttonSpacerHeight, dialogContainer.bounds.size.width, buttonSpacerHeight)]; 234 | lineView.backgroundColor = [UIColor colorWithRed:198.0/255.0 green:198.0/255.0 blue:198.0/255.0 alpha:1.0f]; 235 | [dialogContainer addSubview:lineView]; 236 | // ^^^ 237 | 238 | // Add the custom container if there is any 239 | [dialogContainer addSubview:containerView]; 240 | 241 | // Add the buttons too 242 | [self addButtonsToView:dialogContainer]; 243 | 244 | return dialogContainer; 245 | } 246 | 247 | // Helper function: add buttons to container 248 | - (void)addButtonsToView: (UIView *)container 249 | { 250 | if (buttonTitles==NULL) { return; } 251 | 252 | CGFloat buttonWidth = container.bounds.size.width / [buttonTitles count]; 253 | 254 | for (int i=0; i<[buttonTitles count]; i++) { 255 | 256 | UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom]; 257 | 258 | [closeButton setFrame:CGRectMake(i * buttonWidth, container.bounds.size.height - buttonHeight, buttonWidth, buttonHeight)]; 259 | 260 | [closeButton addTarget:self action:@selector(customIOS7dialogButtonTouchUpInside:) forControlEvents:UIControlEventTouchUpInside]; 261 | [closeButton setTag:i]; 262 | 263 | [closeButton setTitle:[buttonTitles objectAtIndex:i] forState:UIControlStateNormal]; 264 | [closeButton setTitleColor:[UIColor colorWithRed:0.0f green:0.5f blue:1.0f alpha:1.0f] forState:UIControlStateNormal]; 265 | [closeButton setTitleColor:[UIColor colorWithRed:0.2f green:0.2f blue:0.2f alpha:0.5f] forState:UIControlStateHighlighted]; 266 | [closeButton.titleLabel setFont:[UIFont boldSystemFontOfSize:14.0f]]; 267 | closeButton.titleLabel.numberOfLines = 0; 268 | closeButton.titleLabel.textAlignment = NSTextAlignmentCenter; 269 | [closeButton.layer setCornerRadius:kCustomIOSAlertViewCornerRadius]; 270 | 271 | [container addSubview:closeButton]; 272 | } 273 | } 274 | 275 | // Helper function: count and return the dialog's size 276 | - (CGSize)countDialogSize 277 | { 278 | CGFloat dialogWidth = containerView.frame.size.width; 279 | CGFloat dialogHeight = containerView.frame.size.height + buttonHeight + buttonSpacerHeight; 280 | 281 | return CGSizeMake(dialogWidth, dialogHeight); 282 | } 283 | 284 | // Helper function: count and return the screen's size 285 | - (CGSize)countScreenSize 286 | { 287 | if (buttonTitles!=NULL && [buttonTitles count] > 0) { 288 | buttonHeight = kCustomIOSAlertViewDefaultButtonHeight; 289 | buttonSpacerHeight = kCustomIOSAlertViewDefaultButtonSpacerHeight; 290 | } else { 291 | buttonHeight = 0; 292 | buttonSpacerHeight = 0; 293 | } 294 | 295 | CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; 296 | CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; 297 | 298 | // On iOS7, screen width and height doesn't automatically follow orientation 299 | if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { 300 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 301 | if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) { 302 | CGFloat tmp = screenWidth; 303 | screenWidth = screenHeight; 304 | screenHeight = tmp; 305 | } 306 | } 307 | 308 | return CGSizeMake(screenWidth, screenHeight); 309 | } 310 | 311 | #if (defined(__IPHONE_7_0)) 312 | // Add motion effects 313 | - (void)applyMotionEffects { 314 | 315 | if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) { 316 | return; 317 | } 318 | 319 | UIInterpolatingMotionEffect *horizontalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" 320 | type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; 321 | horizontalEffect.minimumRelativeValue = @(-kCustomIOS7MotionEffectExtent); 322 | horizontalEffect.maximumRelativeValue = @( kCustomIOS7MotionEffectExtent); 323 | 324 | UIInterpolatingMotionEffect *verticalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" 325 | type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; 326 | verticalEffect.minimumRelativeValue = @(-kCustomIOS7MotionEffectExtent); 327 | verticalEffect.maximumRelativeValue = @( kCustomIOS7MotionEffectExtent); 328 | 329 | UIMotionEffectGroup *motionEffectGroup = [[UIMotionEffectGroup alloc] init]; 330 | motionEffectGroup.motionEffects = @[horizontalEffect, verticalEffect]; 331 | 332 | [dialogView addMotionEffect:motionEffectGroup]; 333 | } 334 | #endif 335 | 336 | - (void)dealloc 337 | { 338 | [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; 339 | 340 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; 341 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; 342 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 343 | } 344 | 345 | // Rotation changed, on iOS7 346 | - (void)changeOrientationForIOS7 { 347 | 348 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 349 | 350 | CGFloat startRotation = [[self valueForKeyPath:@"layer.transform.rotation.z"] floatValue]; 351 | CGAffineTransform rotation; 352 | 353 | switch (interfaceOrientation) { 354 | case UIInterfaceOrientationLandscapeLeft: 355 | rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 270.0 / 180.0); 356 | break; 357 | 358 | case UIInterfaceOrientationLandscapeRight: 359 | rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 90.0 / 180.0); 360 | break; 361 | 362 | case UIInterfaceOrientationPortraitUpsideDown: 363 | rotation = CGAffineTransformMakeRotation(-startRotation + M_PI * 180.0 / 180.0); 364 | break; 365 | 366 | default: 367 | rotation = CGAffineTransformMakeRotation(-startRotation + 0.0); 368 | break; 369 | } 370 | 371 | [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone 372 | animations:^{ 373 | dialogView.transform = rotation; 374 | 375 | } 376 | completion:nil 377 | ]; 378 | 379 | } 380 | 381 | // Rotation changed, on iOS8 382 | - (void)changeOrientationForIOS8: (NSNotification *)notification { 383 | 384 | CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; 385 | CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; 386 | 387 | [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone 388 | animations:^{ 389 | CGSize dialogSize = [self countDialogSize]; 390 | CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 391 | self.frame = CGRectMake(0, 0, screenWidth, screenHeight); 392 | dialogView.frame = CGRectMake((screenWidth - dialogSize.width) / 2, (screenHeight - keyboardSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height); 393 | } 394 | completion:nil 395 | ]; 396 | 397 | 398 | } 399 | 400 | // Handle device orientation changes 401 | - (void)deviceOrientationDidChange: (NSNotification *)notification 402 | { 403 | // If dialog is attached to the parent view, it probably wants to handle the orientation change itself 404 | if (parentView != NULL) { 405 | return; 406 | } 407 | 408 | if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { 409 | [self changeOrientationForIOS7]; 410 | } else { 411 | [self changeOrientationForIOS8:notification]; 412 | } 413 | } 414 | 415 | // Handle keyboard show/hide changes 416 | - (void)keyboardWillShow: (NSNotification *)notification 417 | { 418 | CGSize screenSize = [self countScreenSize]; 419 | CGSize dialogSize = [self countDialogSize]; 420 | CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 421 | 422 | UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 423 | if (UIInterfaceOrientationIsLandscape(interfaceOrientation) && NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) { 424 | CGFloat tmp = keyboardSize.height; 425 | keyboardSize.height = keyboardSize.width; 426 | keyboardSize.width = tmp; 427 | } 428 | 429 | [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone 430 | animations:^{ 431 | dialogView.frame = CGRectMake((screenSize.width - dialogSize.width) / 2, (screenSize.height - keyboardSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height); 432 | } 433 | completion:nil 434 | ]; 435 | } 436 | 437 | - (void)keyboardWillHide: (NSNotification *)notification 438 | { 439 | CGSize screenSize = [self countScreenSize]; 440 | CGSize dialogSize = [self countDialogSize]; 441 | 442 | [UIView animateWithDuration:0.2f delay:0.0 options:UIViewAnimationOptionTransitionNone 443 | animations:^{ 444 | dialogView.frame = CGRectMake((screenSize.width - dialogSize.width) / 2, (screenSize.height - dialogSize.height) / 2, dialogSize.width, dialogSize.height); 445 | } 446 | completion:nil 447 | ]; 448 | } 449 | 450 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 451 | if (!closeOnTouchUpOutside) { 452 | return; 453 | } 454 | 455 | UITouch *touch = [touches anyObject]; 456 | if ([touch.view isKindOfClass:[CustomIOSAlertView class]]) { 457 | [self close]; 458 | } 459 | } 460 | 461 | @end 462 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // CustomIOSAlertView 4 | // 5 | // Created by Richard on 20/09/2013. 6 | // Copyright (c) 2013-2015 Wimagguc. 7 | // 8 | // Lincesed under The MIT License (MIT) 9 | // http://opensource.org/licenses/MIT 10 | // 11 | 12 | #import 13 | #import "CustomIOSAlertView.h" 14 | 15 | @interface ViewController : UIViewController 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // CustomIOSAlertView 4 | // 5 | // Created by Richard on 20/09/2013. 6 | // Copyright (c) 2013-2015 Wimagguc. 7 | // 8 | // Lincesed under The MIT License (MIT) 9 | // http://opensource.org/licenses/MIT 10 | // 11 | 12 | #import "ViewController.h" 13 | 14 | @interface ViewController () 15 | 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)viewDidLoad 21 | { 22 | [super viewDidLoad]; 23 | 24 | // Just a subtle background color 25 | [self.view setBackgroundColor:[UIColor colorWithRed:0.8f green:0.8f blue:0.8f alpha:1.0f]]; 26 | 27 | // A simple button to launch the demo 28 | UIButton *launchDialog = [UIButton buttonWithType:UIButtonTypeCustom]; 29 | [launchDialog setFrame:CGRectMake(10, 30, self.view.bounds.size.width-20, 50)]; 30 | [launchDialog addTarget:self action:@selector(launchDialog:) forControlEvents:UIControlEventTouchDown]; 31 | [launchDialog setTitle:@"Launch Dialog" forState:UIControlStateNormal]; 32 | [launchDialog setBackgroundColor:[UIColor whiteColor]]; 33 | [launchDialog setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 34 | [launchDialog.layer setBorderWidth:0]; 35 | [launchDialog.layer setCornerRadius:5]; 36 | [self.view addSubview:launchDialog]; 37 | } 38 | 39 | - (IBAction)launchDialog:(id)sender 40 | { 41 | // Here we need to pass a full frame 42 | CustomIOSAlertView *alertView = [[CustomIOSAlertView alloc] init]; 43 | 44 | // Add some custom content to the alert view 45 | [alertView setContainerView:[self createDemoView]]; 46 | 47 | // Modify the parameters 48 | [alertView setButtonTitles:[NSMutableArray arrayWithObjects:@"Close1", @"Close2", @"Close3", nil]]; 49 | [alertView setDelegate:self]; 50 | 51 | // You may use a Block, rather than a delegate. 52 | [alertView setOnButtonTouchUpInside:^(CustomIOSAlertView *alertView, int buttonIndex) { 53 | NSLog(@"Block: Button at position %d is clicked on alertView %d.", buttonIndex, (int)[alertView tag]); 54 | [alertView close]; 55 | }]; 56 | 57 | [alertView setUseMotionEffects:true]; 58 | 59 | // And launch the dialog 60 | [alertView show]; 61 | } 62 | 63 | - (void)customIOS7dialogButtonTouchUpInside: (CustomIOSAlertView *)alertView clickedButtonAtIndex: (NSInteger)buttonIndex 64 | { 65 | NSLog(@"Delegate: Button at position %d is clicked on alertView %d.", (int)buttonIndex, (int)[alertView tag]); 66 | [alertView close]; 67 | } 68 | 69 | - (UIView *)createDemoView 70 | { 71 | UIView *demoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 290, 200)]; 72 | 73 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 270, 180)]; 74 | [imageView setImage:[UIImage imageNamed:@"demo"]]; 75 | [demoView addSubview:imageView]; 76 | 77 | return demoView; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /CustomIOSAlertView/CustomIOSAlertView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CustomIOSAlertView 4 | // 5 | // Created by Richard on 20/09/2013. 6 | // Copyright (c) 2013-2015 Wimagguc. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Docs/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wimagguc/ios-custom-alertview/5bf1b3f9d4b10f878654bb92f0f6c1a53fe36bb0/Docs/screen.png -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | **Please feel free to push back anything you think is useful for the project.** 4 | 5 | Copyright (c) 2013 Richard Dancsi 6 | 7 | Lincesed under [The MIT License](http://opensource.org/licenses/MIT) (MIT) 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Custom iOS AlertView 2 | 3 | `v0.9.5` 4 | 5 | `support for iOS7+` 6 | 7 | The addSubview is not available in UIAlertView since iOS7. The view hierarchy for this class is private and must not be modified. 8 | 9 | As a solution, this class creates an iOS-style dialog which you can extend with any UIViews or buttons. The animations and the looks are copied too and no images or other resources are needed. 10 | 11 | ![A demo screen](Docs/screen.png) 12 | 13 | ## Install 14 | 15 | As simple as adding the following files to your project: 16 | 17 | * CustomIOSAlertView.h 18 | * CustomIOSAlertView.m 19 | 20 | Or use Cocoapods: 21 | 22 | ``` 23 | pod 'CustomIOSAlertView', '~> 0.9.5' 24 | ``` 25 | 26 | ## Change notes 27 | 28 | * Fixed rotation for IOS8 29 | 30 | * Removed 7 from the class name. Just use CustomIOSAlertView from now on, like: [[CustomIOSAlertView alloc] init]; 31 | 32 | * The initWithParentView method is now deprecated. Please use the init method instead, where you don't need to pass a parent view at all. **In case the init doesn't work for you, please leave a note or open an issue here.** 33 | 34 | ## Quick start guide 35 | 36 | 1. Create the UIView object `changed` 37 | 38 | ``` 39 | CustomIOSAlertView *alertView = [[CustomIOSAlertView alloc] init]; 40 | ``` 41 | 42 | 2. Add some custom content to the alert view (optional) 43 | 44 | ``` 45 | UIView *customView ..; 46 | 47 | [alertView setContainerView:customView]; 48 | ``` 49 | 50 | 3. Display the dialog 51 | 52 | ``` 53 | [alertView show]; 54 | ``` 55 | 56 | ## More functions 57 | 58 | * Close the dialog 59 | 60 | ``` 61 | [alertView close]; 62 | ``` 63 | 64 | * To add more buttons, pass a list of titles 65 | 66 | ``` 67 | [alertView setButtonTitles:[NSMutableArray arrayWithObjects:@"Button1", @"Button2", @"Button3", nil]]; 68 | ``` 69 | 70 | * You can remove all buttons by passing nil 71 | 72 | ``` 73 | [alertView setButtonTitles:NULL]; 74 | ``` 75 | 76 | * You can enable or disable the iOS7 parallax effects on the alert view 77 | 78 | ``` 79 | [alertView setUseMotionEffects:TRUE]; 80 | ``` 81 | 82 | * Handle button clicks with a custom delegate 83 | 84 | First, set the delegate: 85 | 86 | ``` 87 | [alertView setDelegate:self]; 88 | ``` 89 | 90 | Then add the delegate methods: 91 | 92 | ``` 93 | - (void)customIOS7dialogButtonTouchUpInside: (CustomIOSAlertView *)alertView clickedButtonAtIndex: (NSInteger)buttonIndex 94 | { 95 | NSLog(@"Button at position %d is clicked on alertView %d.", buttonIndex, [alertView tag]); 96 | } 97 | ``` 98 | 99 | * Handle button clicks with a code block 100 | 101 | ``` 102 | [alertView setOnButtonTouchUpInside:^(CustomIOSAlertView *alertView, int buttonIndex) { 103 | NSLog(@"Block: Button at position %d is clicked on alertView %d.", buttonIndex, [alertView tag]); 104 | [alertView close]; 105 | }]; 106 | ``` 107 | 108 | You can also disable all other delegates by: 109 | 110 | ``` 111 | [alertView setDelegate:self]; 112 | ``` 113 | 114 | ## Todos 115 | 116 | This is a really quick implementation, and there are a few things missing: 117 | 118 | * Adding more buttons: they don't exactly match the look with that of on iOS7 119 | 120 | * Rotation: rotates wrong with the keyboard on 121 | 122 | ## Special thanks to 123 | 124 | * [@tamasdancsi](https://github.com/tamasdancsi) for his support with the initial code 125 | * [@dingosky](https://github.com/dingosky) for his work on the parallax effects code 126 | * [@raspu](https://github.com/raspu) for his work on the protocol delegates, iOS6 support and onButtonClick blocks 127 | * [@sbandol](https://github.com/sbandol) for his idea on adding the AlertView as the top most view in the hierarchy 128 | * [@scorpiozj](https://github.com/scorpiozj) for his work on the rotation code 129 | * [@kwent](https://github.com/kwent) for adding performance optimisations 130 | * [@thomasaw](https://github.com/thomasaw) for the refract on the deprecated initWithParentview 131 | * [@yiboyu](https://github.com/yiboyu) for the multi-line button fix 132 | * [@logicxd](https://github.com/logicxd) for the close-on-touchup-outside code 133 | 134 | ## License 135 | 136 | MIT. Please read [LICENSE.md](https://github.com/wimagguc/ios-custom-alertview/blob/master/LICENSE.md) for more info. 137 | 138 | ## Other projects 139 | 140 | Check out [Appwoodoo](http://www.appwoodoo.com/) for push notifications and remote app control service. Open source SDKs are available on Github: [github.com/appwoodoo](https://github.com/appwoodoo?tab=repositories). 141 | 142 | Some more of my free stuff for web devs at [Github](https://github.com/wimagguc?tab=repositories). 143 | 144 | Project updates [newsletter](http://wimagguc.us4.list-manage.com/subscribe/post?u=83343dbd708d35d76618f66c5&id=da7cc7f1dc) 145 | 146 | ## About 147 | 148 | Richard Dancsi 149 | [www.wimagguc.com](http://www.wimagguc.com/) 150 | 151 | twitter: [@wimagguc](http://twitter.com/wimagguc) 152 | linkedin: [linkedin.com/in/richarddancsi](http://linkedin.com/in/richarddancsi) 153 | --------------------------------------------------------------------------------