├── .gitignore ├── Example ├── Example.xcodeproj │ └── project.pbxproj ├── Example │ ├── Example-Info.plist │ ├── Example-Prefix.pch │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── PXLAppDelegate.h │ ├── PXLAppDelegate.m │ ├── PXLViewController.h │ ├── PXLViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── ExampleTests │ ├── ExampleTests-Info.plist │ ├── ExampleTests.m │ └── en.lproj │ └── InfoPlist.strings ├── LICENSE ├── PXLActionSheet.podspec ├── PXLActionSheet ├── PXLActionSheet.h ├── PXLActionSheet.m ├── PXLActionSheetTheme.h └── PXLActionSheetTheme.m ├── README.markdown └── screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.pbxuser 3 | *.perspectivev3 4 | *.xcworkspace 5 | xcuserdata 6 | .DS_store 7 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 962D84A11989E6BB005221C2 /* PXLActionSheetTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 962D84A01989E6BB005221C2 /* PXLActionSheetTheme.m */; }; 11 | 96CAC1EA1989CB1800F26FBC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96CAC1E91989CB1800F26FBC /* Foundation.framework */; }; 12 | 96CAC1EC1989CB1800F26FBC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96CAC1EB1989CB1800F26FBC /* CoreGraphics.framework */; }; 13 | 96CAC1EE1989CB1800F26FBC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96CAC1ED1989CB1800F26FBC /* UIKit.framework */; }; 14 | 96CAC1F41989CB1800F26FBC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96CAC1F21989CB1800F26FBC /* InfoPlist.strings */; }; 15 | 96CAC1F61989CB1800F26FBC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CAC1F51989CB1800F26FBC /* main.m */; }; 16 | 96CAC1FA1989CB1800F26FBC /* PXLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CAC1F91989CB1800F26FBC /* PXLAppDelegate.m */; }; 17 | 96CAC1FC1989CB1800F26FBC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 96CAC1FB1989CB1800F26FBC /* Images.xcassets */; }; 18 | 96CAC2031989CB1800F26FBC /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96CAC2021989CB1800F26FBC /* XCTest.framework */; }; 19 | 96CAC2041989CB1800F26FBC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96CAC1E91989CB1800F26FBC /* Foundation.framework */; }; 20 | 96CAC2051989CB1800F26FBC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96CAC1ED1989CB1800F26FBC /* UIKit.framework */; }; 21 | 96CAC20D1989CB1800F26FBC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96CAC20B1989CB1800F26FBC /* InfoPlist.strings */; }; 22 | 96CAC20F1989CB1800F26FBC /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CAC20E1989CB1800F26FBC /* ExampleTests.m */; }; 23 | 96CAC21A1989CC0300F26FBC /* PXLViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CAC2191989CC0300F26FBC /* PXLViewController.m */; }; 24 | 96CAC21E1989CC3C00F26FBC /* PXLActionSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = 96CAC21D1989CC3C00F26FBC /* PXLActionSheet.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | 96CAC2061989CB1800F26FBC /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 96CAC1DE1989CB1800F26FBC /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 96CAC1E51989CB1800F26FBC; 33 | remoteInfo = Example; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 962D849F1989E6BB005221C2 /* PXLActionSheetTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PXLActionSheetTheme.h; sourceTree = ""; }; 39 | 962D84A01989E6BB005221C2 /* PXLActionSheetTheme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PXLActionSheetTheme.m; sourceTree = ""; }; 40 | 96CAC1E61989CB1800F26FBC /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 96CAC1E91989CB1800F26FBC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 42 | 96CAC1EB1989CB1800F26FBC /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 43 | 96CAC1ED1989CB1800F26FBC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 44 | 96CAC1F11989CB1800F26FBC /* Example-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Example-Info.plist"; sourceTree = ""; }; 45 | 96CAC1F31989CB1800F26FBC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 46 | 96CAC1F51989CB1800F26FBC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | 96CAC1F71989CB1800F26FBC /* Example-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Example-Prefix.pch"; sourceTree = ""; }; 48 | 96CAC1F81989CB1800F26FBC /* PXLAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PXLAppDelegate.h; sourceTree = ""; }; 49 | 96CAC1F91989CB1800F26FBC /* PXLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PXLAppDelegate.m; sourceTree = ""; }; 50 | 96CAC1FB1989CB1800F26FBC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 51 | 96CAC2011989CB1800F26FBC /* ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 96CAC2021989CB1800F26FBC /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 53 | 96CAC20A1989CB1800F26FBC /* ExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleTests-Info.plist"; sourceTree = ""; }; 54 | 96CAC20C1989CB1800F26FBC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 55 | 96CAC20E1989CB1800F26FBC /* ExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleTests.m; sourceTree = ""; }; 56 | 96CAC2181989CC0300F26FBC /* PXLViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PXLViewController.h; sourceTree = ""; }; 57 | 96CAC2191989CC0300F26FBC /* PXLViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PXLViewController.m; sourceTree = ""; }; 58 | 96CAC21C1989CC3C00F26FBC /* PXLActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PXLActionSheet.h; sourceTree = ""; }; 59 | 96CAC21D1989CC3C00F26FBC /* PXLActionSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PXLActionSheet.m; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 96CAC1E31989CB1800F26FBC /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | 96CAC1EC1989CB1800F26FBC /* CoreGraphics.framework in Frameworks */, 68 | 96CAC1EE1989CB1800F26FBC /* UIKit.framework in Frameworks */, 69 | 96CAC1EA1989CB1800F26FBC /* Foundation.framework in Frameworks */, 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | 96CAC1FE1989CB1800F26FBC /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | 96CAC2031989CB1800F26FBC /* XCTest.framework in Frameworks */, 78 | 96CAC2051989CB1800F26FBC /* UIKit.framework in Frameworks */, 79 | 96CAC2041989CB1800F26FBC /* Foundation.framework in Frameworks */, 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | /* End PBXFrameworksBuildPhase section */ 84 | 85 | /* Begin PBXGroup section */ 86 | 96CAC1DD1989CB1800F26FBC = { 87 | isa = PBXGroup; 88 | children = ( 89 | 96CAC21B1989CC0D00F26FBC /* PXLActionSheet */, 90 | 96CAC1EF1989CB1800F26FBC /* Example */, 91 | 96CAC2081989CB1800F26FBC /* ExampleTests */, 92 | 96CAC1E81989CB1800F26FBC /* Frameworks */, 93 | 96CAC1E71989CB1800F26FBC /* Products */, 94 | ); 95 | sourceTree = ""; 96 | }; 97 | 96CAC1E71989CB1800F26FBC /* Products */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 96CAC1E61989CB1800F26FBC /* Example.app */, 101 | 96CAC2011989CB1800F26FBC /* ExampleTests.xctest */, 102 | ); 103 | name = Products; 104 | sourceTree = ""; 105 | }; 106 | 96CAC1E81989CB1800F26FBC /* Frameworks */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 96CAC1E91989CB1800F26FBC /* Foundation.framework */, 110 | 96CAC1EB1989CB1800F26FBC /* CoreGraphics.framework */, 111 | 96CAC1ED1989CB1800F26FBC /* UIKit.framework */, 112 | 96CAC2021989CB1800F26FBC /* XCTest.framework */, 113 | ); 114 | name = Frameworks; 115 | sourceTree = ""; 116 | }; 117 | 96CAC1EF1989CB1800F26FBC /* Example */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 96CAC1F81989CB1800F26FBC /* PXLAppDelegate.h */, 121 | 96CAC1F91989CB1800F26FBC /* PXLAppDelegate.m */, 122 | 96CAC2181989CC0300F26FBC /* PXLViewController.h */, 123 | 96CAC2191989CC0300F26FBC /* PXLViewController.m */, 124 | 96CAC1FB1989CB1800F26FBC /* Images.xcassets */, 125 | 96CAC1F01989CB1800F26FBC /* Supporting Files */, 126 | ); 127 | path = Example; 128 | sourceTree = ""; 129 | }; 130 | 96CAC1F01989CB1800F26FBC /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 96CAC1F11989CB1800F26FBC /* Example-Info.plist */, 134 | 96CAC1F21989CB1800F26FBC /* InfoPlist.strings */, 135 | 96CAC1F51989CB1800F26FBC /* main.m */, 136 | 96CAC1F71989CB1800F26FBC /* Example-Prefix.pch */, 137 | ); 138 | name = "Supporting Files"; 139 | sourceTree = ""; 140 | }; 141 | 96CAC2081989CB1800F26FBC /* ExampleTests */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 96CAC20E1989CB1800F26FBC /* ExampleTests.m */, 145 | 96CAC2091989CB1800F26FBC /* Supporting Files */, 146 | ); 147 | path = ExampleTests; 148 | sourceTree = ""; 149 | }; 150 | 96CAC2091989CB1800F26FBC /* Supporting Files */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 96CAC20A1989CB1800F26FBC /* ExampleTests-Info.plist */, 154 | 96CAC20B1989CB1800F26FBC /* InfoPlist.strings */, 155 | ); 156 | name = "Supporting Files"; 157 | sourceTree = ""; 158 | }; 159 | 96CAC21B1989CC0D00F26FBC /* PXLActionSheet */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 96CAC21C1989CC3C00F26FBC /* PXLActionSheet.h */, 163 | 96CAC21D1989CC3C00F26FBC /* PXLActionSheet.m */, 164 | 962D849F1989E6BB005221C2 /* PXLActionSheetTheme.h */, 165 | 962D84A01989E6BB005221C2 /* PXLActionSheetTheme.m */, 166 | ); 167 | name = PXLActionSheet; 168 | path = ../PXLActionSheet; 169 | sourceTree = ""; 170 | }; 171 | /* End PBXGroup section */ 172 | 173 | /* Begin PBXNativeTarget section */ 174 | 96CAC1E51989CB1800F26FBC /* Example */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = 96CAC2121989CB1800F26FBC /* Build configuration list for PBXNativeTarget "Example" */; 177 | buildPhases = ( 178 | 96CAC1E21989CB1800F26FBC /* Sources */, 179 | 96CAC1E31989CB1800F26FBC /* Frameworks */, 180 | 96CAC1E41989CB1800F26FBC /* Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | ); 186 | name = Example; 187 | productName = Example; 188 | productReference = 96CAC1E61989CB1800F26FBC /* Example.app */; 189 | productType = "com.apple.product-type.application"; 190 | }; 191 | 96CAC2001989CB1800F26FBC /* ExampleTests */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = 96CAC2151989CB1800F26FBC /* Build configuration list for PBXNativeTarget "ExampleTests" */; 194 | buildPhases = ( 195 | 96CAC1FD1989CB1800F26FBC /* Sources */, 196 | 96CAC1FE1989CB1800F26FBC /* Frameworks */, 197 | 96CAC1FF1989CB1800F26FBC /* Resources */, 198 | ); 199 | buildRules = ( 200 | ); 201 | dependencies = ( 202 | 96CAC2071989CB1800F26FBC /* PBXTargetDependency */, 203 | ); 204 | name = ExampleTests; 205 | productName = ExampleTests; 206 | productReference = 96CAC2011989CB1800F26FBC /* ExampleTests.xctest */; 207 | productType = "com.apple.product-type.bundle.unit-test"; 208 | }; 209 | /* End PBXNativeTarget section */ 210 | 211 | /* Begin PBXProject section */ 212 | 96CAC1DE1989CB1800F26FBC /* Project object */ = { 213 | isa = PBXProject; 214 | attributes = { 215 | CLASSPREFIX = PXL; 216 | LastUpgradeCheck = 0510; 217 | ORGANIZATIONNAME = "Jason Silberman"; 218 | TargetAttributes = { 219 | 96CAC2001989CB1800F26FBC = { 220 | TestTargetID = 96CAC1E51989CB1800F26FBC; 221 | }; 222 | }; 223 | }; 224 | buildConfigurationList = 96CAC1E11989CB1800F26FBC /* Build configuration list for PBXProject "Example" */; 225 | compatibilityVersion = "Xcode 3.2"; 226 | developmentRegion = English; 227 | hasScannedForEncodings = 0; 228 | knownRegions = ( 229 | en, 230 | ); 231 | mainGroup = 96CAC1DD1989CB1800F26FBC; 232 | productRefGroup = 96CAC1E71989CB1800F26FBC /* Products */; 233 | projectDirPath = ""; 234 | projectRoot = ""; 235 | targets = ( 236 | 96CAC1E51989CB1800F26FBC /* Example */, 237 | 96CAC2001989CB1800F26FBC /* ExampleTests */, 238 | ); 239 | }; 240 | /* End PBXProject section */ 241 | 242 | /* Begin PBXResourcesBuildPhase section */ 243 | 96CAC1E41989CB1800F26FBC /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 96CAC1F41989CB1800F26FBC /* InfoPlist.strings in Resources */, 248 | 96CAC1FC1989CB1800F26FBC /* Images.xcassets in Resources */, 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | 96CAC1FF1989CB1800F26FBC /* Resources */ = { 253 | isa = PBXResourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | 96CAC20D1989CB1800F26FBC /* InfoPlist.strings in Resources */, 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | /* End PBXResourcesBuildPhase section */ 261 | 262 | /* Begin PBXSourcesBuildPhase section */ 263 | 96CAC1E21989CB1800F26FBC /* Sources */ = { 264 | isa = PBXSourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | 96CAC1F61989CB1800F26FBC /* main.m in Sources */, 268 | 96CAC21A1989CC0300F26FBC /* PXLViewController.m in Sources */, 269 | 96CAC21E1989CC3C00F26FBC /* PXLActionSheet.m in Sources */, 270 | 962D84A11989E6BB005221C2 /* PXLActionSheetTheme.m in Sources */, 271 | 96CAC1FA1989CB1800F26FBC /* PXLAppDelegate.m in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | 96CAC1FD1989CB1800F26FBC /* Sources */ = { 276 | isa = PBXSourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | 96CAC20F1989CB1800F26FBC /* ExampleTests.m in Sources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | /* End PBXSourcesBuildPhase section */ 284 | 285 | /* Begin PBXTargetDependency section */ 286 | 96CAC2071989CB1800F26FBC /* PBXTargetDependency */ = { 287 | isa = PBXTargetDependency; 288 | target = 96CAC1E51989CB1800F26FBC /* Example */; 289 | targetProxy = 96CAC2061989CB1800F26FBC /* PBXContainerItemProxy */; 290 | }; 291 | /* End PBXTargetDependency section */ 292 | 293 | /* Begin PBXVariantGroup section */ 294 | 96CAC1F21989CB1800F26FBC /* InfoPlist.strings */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 96CAC1F31989CB1800F26FBC /* en */, 298 | ); 299 | name = InfoPlist.strings; 300 | sourceTree = ""; 301 | }; 302 | 96CAC20B1989CB1800F26FBC /* InfoPlist.strings */ = { 303 | isa = PBXVariantGroup; 304 | children = ( 305 | 96CAC20C1989CB1800F26FBC /* en */, 306 | ); 307 | name = InfoPlist.strings; 308 | sourceTree = ""; 309 | }; 310 | /* End PBXVariantGroup section */ 311 | 312 | /* Begin XCBuildConfiguration section */ 313 | 96CAC2101989CB1800F26FBC /* Debug */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 318 | CLANG_CXX_LIBRARY = "libc++"; 319 | CLANG_ENABLE_MODULES = YES; 320 | CLANG_ENABLE_OBJC_ARC = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 324 | CLANG_WARN_EMPTY_BODY = YES; 325 | CLANG_WARN_ENUM_CONVERSION = YES; 326 | CLANG_WARN_INT_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 329 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 330 | COPY_PHASE_STRIP = NO; 331 | GCC_C_LANGUAGE_STANDARD = gnu99; 332 | GCC_DYNAMIC_NO_PIC = NO; 333 | GCC_OPTIMIZATION_LEVEL = 0; 334 | GCC_PREPROCESSOR_DEFINITIONS = ( 335 | "DEBUG=1", 336 | "$(inherited)", 337 | ); 338 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 339 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 340 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 341 | GCC_WARN_UNDECLARED_SELECTOR = YES; 342 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 343 | GCC_WARN_UNUSED_FUNCTION = YES; 344 | GCC_WARN_UNUSED_VARIABLE = YES; 345 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 346 | ONLY_ACTIVE_ARCH = YES; 347 | SDKROOT = iphoneos; 348 | }; 349 | name = Debug; 350 | }; 351 | 96CAC2111989CB1800F26FBC /* Release */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ALWAYS_SEARCH_USER_PATHS = NO; 355 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 356 | CLANG_CXX_LIBRARY = "libc++"; 357 | CLANG_ENABLE_MODULES = YES; 358 | CLANG_ENABLE_OBJC_ARC = YES; 359 | CLANG_WARN_BOOL_CONVERSION = YES; 360 | CLANG_WARN_CONSTANT_CONVERSION = YES; 361 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 362 | CLANG_WARN_EMPTY_BODY = YES; 363 | CLANG_WARN_ENUM_CONVERSION = YES; 364 | CLANG_WARN_INT_CONVERSION = YES; 365 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 366 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 367 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 368 | COPY_PHASE_STRIP = YES; 369 | ENABLE_NS_ASSERTIONS = NO; 370 | GCC_C_LANGUAGE_STANDARD = gnu99; 371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 373 | GCC_WARN_UNDECLARED_SELECTOR = YES; 374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 375 | GCC_WARN_UNUSED_FUNCTION = YES; 376 | GCC_WARN_UNUSED_VARIABLE = YES; 377 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 378 | SDKROOT = iphoneos; 379 | VALIDATE_PRODUCT = YES; 380 | }; 381 | name = Release; 382 | }; 383 | 96CAC2131989CB1800F26FBC /* Debug */ = { 384 | isa = XCBuildConfiguration; 385 | buildSettings = { 386 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 387 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 388 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 389 | GCC_PREFIX_HEADER = "Example/Example-Prefix.pch"; 390 | INFOPLIST_FILE = "Example/Example-Info.plist"; 391 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 392 | PRODUCT_NAME = "$(TARGET_NAME)"; 393 | WRAPPER_EXTENSION = app; 394 | }; 395 | name = Debug; 396 | }; 397 | 96CAC2141989CB1800F26FBC /* Release */ = { 398 | isa = XCBuildConfiguration; 399 | buildSettings = { 400 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 401 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 402 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 403 | GCC_PREFIX_HEADER = "Example/Example-Prefix.pch"; 404 | INFOPLIST_FILE = "Example/Example-Info.plist"; 405 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 406 | PRODUCT_NAME = "$(TARGET_NAME)"; 407 | WRAPPER_EXTENSION = app; 408 | }; 409 | name = Release; 410 | }; 411 | 96CAC2161989CB1800F26FBC /* Debug */ = { 412 | isa = XCBuildConfiguration; 413 | buildSettings = { 414 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; 415 | FRAMEWORK_SEARCH_PATHS = ( 416 | "$(SDKROOT)/Developer/Library/Frameworks", 417 | "$(inherited)", 418 | "$(DEVELOPER_FRAMEWORKS_DIR)", 419 | ); 420 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 421 | GCC_PREFIX_HEADER = "Example/Example-Prefix.pch"; 422 | GCC_PREPROCESSOR_DEFINITIONS = ( 423 | "DEBUG=1", 424 | "$(inherited)", 425 | ); 426 | INFOPLIST_FILE = "ExampleTests/ExampleTests-Info.plist"; 427 | PRODUCT_NAME = "$(TARGET_NAME)"; 428 | TEST_HOST = "$(BUNDLE_LOADER)"; 429 | WRAPPER_EXTENSION = xctest; 430 | }; 431 | name = Debug; 432 | }; 433 | 96CAC2171989CB1800F26FBC /* Release */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; 437 | FRAMEWORK_SEARCH_PATHS = ( 438 | "$(SDKROOT)/Developer/Library/Frameworks", 439 | "$(inherited)", 440 | "$(DEVELOPER_FRAMEWORKS_DIR)", 441 | ); 442 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 443 | GCC_PREFIX_HEADER = "Example/Example-Prefix.pch"; 444 | INFOPLIST_FILE = "ExampleTests/ExampleTests-Info.plist"; 445 | PRODUCT_NAME = "$(TARGET_NAME)"; 446 | TEST_HOST = "$(BUNDLE_LOADER)"; 447 | WRAPPER_EXTENSION = xctest; 448 | }; 449 | name = Release; 450 | }; 451 | /* End XCBuildConfiguration section */ 452 | 453 | /* Begin XCConfigurationList section */ 454 | 96CAC1E11989CB1800F26FBC /* Build configuration list for PBXProject "Example" */ = { 455 | isa = XCConfigurationList; 456 | buildConfigurations = ( 457 | 96CAC2101989CB1800F26FBC /* Debug */, 458 | 96CAC2111989CB1800F26FBC /* Release */, 459 | ); 460 | defaultConfigurationIsVisible = 0; 461 | defaultConfigurationName = Release; 462 | }; 463 | 96CAC2121989CB1800F26FBC /* Build configuration list for PBXNativeTarget "Example" */ = { 464 | isa = XCConfigurationList; 465 | buildConfigurations = ( 466 | 96CAC2131989CB1800F26FBC /* Debug */, 467 | 96CAC2141989CB1800F26FBC /* Release */, 468 | ); 469 | defaultConfigurationIsVisible = 0; 470 | defaultConfigurationName = Release; 471 | }; 472 | 96CAC2151989CB1800F26FBC /* Build configuration list for PBXNativeTarget "ExampleTests" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | 96CAC2161989CB1800F26FBC /* Debug */, 476 | 96CAC2171989CB1800F26FBC /* Release */, 477 | ); 478 | defaultConfigurationIsVisible = 0; 479 | defaultConfigurationName = Release; 480 | }; 481 | /* End XCConfigurationList section */ 482 | }; 483 | rootObject = 96CAC1DE1989CB1800F26FBC /* Project object */; 484 | } 485 | -------------------------------------------------------------------------------- /Example/Example/Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | co.j99.pxlactionsheet 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/Example/Example-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_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/Example/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" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/PXLAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // PXLAppDelegate.h 3 | // Example 4 | // 5 | // Created by Jason Silberman on 7/30/14. 6 | // Copyright (c) 2014 Jason Silberman. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PXLAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/Example/PXLAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // PXLAppDelegate.m 3 | // Example 4 | // 5 | // Created by Jason Silberman on 7/30/14. 6 | // Copyright (c) 2014 Jason Silberman. All rights reserved. 7 | // 8 | 9 | #import "PXLAppDelegate.h" 10 | #import "PXLViewController.h" 11 | 12 | @implementation PXLAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 15 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 16 | 17 | self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[PXLViewController alloc] init]]; 18 | 19 | self.window.backgroundColor = [UIColor whiteColor]; 20 | [self.window makeKeyAndVisible]; 21 | return YES; 22 | } 23 | @end 24 | -------------------------------------------------------------------------------- /Example/Example/PXLViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PXLViewController.h 3 | // Example 4 | // 5 | // Created by Jason Silberman on 7/30/14. 6 | // Copyright (c) 2014 Jason Silberman. All rights reserved. 7 | // 8 | 9 | @interface PXLViewController : UIViewController 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Example/Example/PXLViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PXLViewController.m 3 | // Example 4 | // 5 | // Created by Jason Silberman on 7/30/14. 6 | // Copyright (c) 2014 Jason Silberman. All rights reserved. 7 | // 8 | 9 | #import "PXLViewController.h" 10 | #import "PXLActionSheet.h" 11 | #import "PXLActionSheetTheme.h" 12 | 13 | @interface PXLViewController () 14 | 15 | @end 16 | 17 | @implementation PXLViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | self.title = @"PXLActionSheet"; 23 | 24 | self.view.backgroundColor = [UIColor colorWithRed:0.082 green:0.541 blue:0.792 alpha:1]; 25 | 26 | UILabel *label = [[UILabel alloc] init]; 27 | label.translatesAutoresizingMaskIntoConstraints = NO; 28 | label.text = @"Tap to show"; 29 | label.font = [UIFont fontWithName:@"Avenir" size:20]; 30 | label.textColor = [UIColor whiteColor]; 31 | label.userInteractionEnabled = YES; 32 | [self.view addSubview:label]; 33 | 34 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]; 35 | [label addGestureRecognizer:tap]; 36 | 37 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]]; 38 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]]; 39 | } 40 | 41 | - (void)tap:(UITapGestureRecognizer *)gestureRecognizer { 42 | if (gestureRecognizer.state == UIGestureRecognizerStateEnded) { 43 | 44 | [PXLActionSheet showInView:self.view withTheme:[PXLActionSheetTheme defaultTheme] title:@"A new customizable replacement for UIActionSheet." cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@[@"Custom Fonts", @"Custom Colors", @"And More!"] tapBlock:^(PXLActionSheet *actionSheet, NSInteger tappedButtonIndex) { 45 | NSLog(@"tapped at %ld", (long)tappedButtonIndex); 46 | }]; 47 | 48 | } 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Example/Example/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Example/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Example 4 | // 5 | // Created by Jason Silberman on 7/30/14. 6 | // Copyright (c) 2014 Jason Silberman. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "PXLAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([PXLAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/ExampleTests/ExampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | co.j99.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/ExampleTests/ExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleTests.m 3 | // ExampleTests 4 | // 5 | // Created by Jason Silberman on 7/30/14. 6 | // Copyright (c) 2014 Jason Silberman. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ExampleTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation ExampleTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Example/ExampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jason Silberman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PXLActionSheet.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'PXLActionSheet' 3 | spec.version = '1.0.2' 4 | spec.summary = 'A new customizable replacement for UIActionSheet.' 5 | spec.homepage = 'https://github.com/jasonsilberman/pxlactionsheet' 6 | spec.author = { 'Jason Silberman' => 'j@j99.co' } 7 | spec.source = { :git => 'https://github.com/jasonsilberman/pxlactionsheet.git', :tag => "v#{spec.version}" } 8 | spec.requires_arc = true 9 | spec.license = { :type => 'MIT', :file => 'LICENSE' } 10 | spec.frameworks = 'Foundation', 'UIKit' 11 | 12 | spec.platform = :ios, '7.0' 13 | spec.ios.deployment_target = '7.0' 14 | 15 | spec.source_files = 'PXLActionSheet/*.{h,m}' 16 | end 17 | -------------------------------------------------------------------------------- /PXLActionSheet/PXLActionSheet.h: -------------------------------------------------------------------------------- 1 | // 2 | // PXLActionSheet.h 3 | // PXLActionSheet 4 | // 5 | // Copyright (c) 2014 Jason Silberman 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | // 25 | 26 | @class PXLActionSheet; 27 | @class PXLActionSheetTheme; 28 | 29 | typedef NS_ENUM(NSInteger, PXLActionSheetVisibility) { 30 | PXLActionSheetVisibilityVisible, 31 | PXLActionSheetVisibilityHidden 32 | }; 33 | 34 | typedef void (^PXLActionSheetTapBlock) (PXLActionSheet * actionSheet, NSInteger tappedButtonIndex); 35 | 36 | NSString *NSStringFromActionSheetVisibility(PXLActionSheetVisibility visibility); 37 | 38 | @protocol PXLActionSheetDelegate; 39 | 40 | @interface PXLActionSheet : UIView 41 | 42 | ///------------------------------------------ 43 | /// @name Creating and Showing Action Sheets 44 | ///------------------------------------------ 45 | 46 | 47 | /** 48 | Creates a PXLActionSheet and shows it. 49 | 50 | @param view The view to show the action sheet in 51 | @param theme The PXLActionSheetTheme to use 52 | @param title The title of the action sheet 53 | @param cancelButtonTitle The title of the cancel button 54 | @param destructiveButtonTitle The title of the destructive button 55 | @param otherButtonTitles An `NSArray` of button titles 56 | @param tapBlock The tap block to be called when a button was pressed 57 | 58 | @return The PXLActionSheet created 59 | */ 60 | + (instancetype)showInView:(UIView *)view withTheme:(PXLActionSheetTheme *)theme title:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles tapBlock:(PXLActionSheetTapBlock)tapBlock; 61 | 62 | /** 63 | Creates a PXLActionSheet. 64 | 65 | @param theme The PXLActionSheetTheme to use 66 | @param title The title of the action sheet 67 | @param cancelButtonTitle The title of the cancel button 68 | @param destructiveButtonTitle The title of the destructive button 69 | @param otherButtonTitles An `NSArray` of button titles 70 | @param tapBlock The tap block to be called when a button was pressed 71 | 72 | @return The PXLActionSheet created 73 | */ 74 | - (instancetype)initWithTheme:(PXLActionSheetTheme *)theme title:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles tapBlock:(PXLActionSheetTapBlock)tapBlock; 75 | 76 | /** 77 | Show the receiver in the given view. 78 | 79 | @param view The view the PXLActionSheet is shown in 80 | */ 81 | - (void)showInView:(UIView *)view; 82 | 83 | ///------------------ 84 | /// @name Properties 85 | ///------------------ 86 | 87 | /** 88 | The visibilty of the action sheet. 89 | */ 90 | @property (nonatomic) PXLActionSheetVisibility visibilty; 91 | 92 | /** 93 | The delegate of the action sheet. 94 | */ 95 | @property (nonatomic, weak) id delegate; 96 | 97 | @end 98 | 99 | @protocol PXLActionSheetDelegate 100 | 101 | @optional 102 | 103 | /** 104 | The delegate method to be called when the action sheet changed visibility. 105 | 106 | @param actionSheet The PXLActionSheet 107 | @param visibilty The new visibilty of the action sheet 108 | */ 109 | - (void)actionSheet:(PXLActionSheet *)actionSheet didChangeVisibility:(PXLActionSheetVisibility)visibilty; 110 | 111 | @end -------------------------------------------------------------------------------- /PXLActionSheet/PXLActionSheet.m: -------------------------------------------------------------------------------- 1 | // 2 | // PXLActionSheet.m 3 | // PXLActionSheet 4 | // 5 | // Copyright (c) 2014 Jason Silberman 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | // 25 | 26 | #import "PXLActionSheet.h" 27 | #import "PXLActionSheetTheme.h" 28 | 29 | // Padding 30 | static const CGFloat PXLActionSheetButtonVerticalPadding = 10.0; 31 | static const CGFloat PXLActionSheetButtonHorizontalPadding = 10.0; 32 | static const CGFloat PXLActionSheetTitlePadding = 10.0; 33 | 34 | // Heights 35 | static const CGFloat PXLActionSheetButtonHeight = 44.0; 36 | 37 | NSString *NSStringFromActionSheetVisibility(PXLActionSheetVisibility visibility) { 38 | if (visibility == PXLActionSheetVisibilityHidden) { 39 | return @"PXLActionSheetVisibilityHidden"; 40 | } else if (visibility == PXLActionSheetVisibilityVisible) { 41 | return @"PXLActionSheetVisibilityVisible"; 42 | } else { 43 | return @"NaN"; 44 | } 45 | } 46 | 47 | #pragma mark - UIButton+BackgroundColorForState Category 48 | 49 | @interface UIButton (BackgroundColorForState) 50 | 51 | - (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state; 52 | 53 | @end 54 | 55 | @implementation UIButton (BackgroundColorForState) 56 | 57 | - (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state { 58 | UIImage *img = nil; 59 | 60 | CGRect rect = CGRectMake(0, 0, 2, 2); 61 | UIGraphicsBeginImageContext(rect.size); 62 | CGContextRef context = UIGraphicsGetCurrentContext(); 63 | CGContextSetFillColorWithColor(context, backgroundColor.CGColor); 64 | CGContextFillRect(context, rect); 65 | 66 | img = UIGraphicsGetImageFromCurrentImageContext(); 67 | 68 | UIGraphicsEndImageContext(); 69 | 70 | [self setBackgroundImage:img forState:state]; 71 | } 72 | 73 | @end 74 | 75 | #pragma mark - UIView+RoundCornersMask Category 76 | 77 | @interface UIView (CornerRadiusWithCorners) 78 | 79 | - (void)applyCornerRadiusMaskForCorners:(UIRectCorner)corners withRadius:(CGFloat)radius; 80 | 81 | @end 82 | 83 | @implementation UIView (CornerRadiusWithCorners) 84 | 85 | - (void)applyCornerRadiusMaskForCorners:(UIRectCorner)corners withRadius:(CGFloat)radius { 86 | UIBezierPath *rounded = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)]; 87 | 88 | CAShapeLayer *shape = [[CAShapeLayer alloc] init]; 89 | [shape setPath:rounded.CGPath]; 90 | 91 | self.layer.mask = shape; 92 | } 93 | 94 | @end 95 | 96 | @interface PXLActionSheet () 97 | @property (nonatomic, copy) PXLActionSheetTapBlock tapBlock; 98 | @property (nonatomic) NSString *title; 99 | @property (nonatomic) NSString *cancelButtonTitle; 100 | @property (nonatomic) NSString *destructiveButtonTitle; 101 | @property (nonatomic) NSArray *otherButtonTitles; 102 | @property (nonatomic) UIView *containerView; 103 | 104 | // UI 105 | @property (nonatomic) UIView *actionSheetBackgroundView; 106 | @property (nonatomic) UILabel *titleLabel; 107 | @property (nonatomic) UIButton *cancelButton; 108 | 109 | @property (nonatomic) UIView *containerSnapShotView; 110 | 111 | @property (nonatomic) PXLActionSheetTheme *theme; 112 | 113 | @end 114 | 115 | @implementation PXLActionSheet 116 | 117 | #pragma mark - Init 118 | 119 | + (instancetype)showInView:(UIView *)view withTheme:(PXLActionSheetTheme *)theme title:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles tapBlock:(PXLActionSheetTapBlock)tapBlock { 120 | 121 | PXLActionSheet *actionSheet = [[PXLActionSheet alloc] initWithTheme:theme title:title cancelButtonTitle:cancelButtonTitle destructiveButtonTitle:destructiveButtonTitle otherButtonTitles:otherButtonTitles tapBlock:tapBlock]; 122 | [actionSheet showInView:view]; 123 | return actionSheet; 124 | } 125 | 126 | - (instancetype)initWithTheme:(PXLActionSheetTheme *)theme title:(NSString *)title cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSArray *)otherButtonTitles tapBlock:(PXLActionSheetTapBlock)tapBlock { 127 | 128 | self = [super init]; 129 | if (self) { 130 | _title = title; 131 | _cancelButtonTitle = cancelButtonTitle; 132 | _destructiveButtonTitle = destructiveButtonTitle; 133 | _otherButtonTitles = otherButtonTitles; 134 | _tapBlock = tapBlock; 135 | 136 | _visibilty = PXLActionSheetVisibilityHidden; 137 | _theme = theme; 138 | 139 | if (! self.cancelButtonTitle) { 140 | [[NSException exceptionWithName:@"PXLActionSheetException" reason:@"Missing cancel button title." userInfo:nil] raise]; 141 | } 142 | 143 | self.backgroundColor = self.theme.backdropShadowColor; 144 | self.isAccessibilityElement = NO; 145 | } 146 | 147 | return self; 148 | } 149 | 150 | - (void)addButtonSubViewsToView:(UIView *)view { 151 | __block CGFloat yPos = CGRectGetMaxY(self.titleLabel.frame) ? CGRectGetMaxY(self.titleLabel.frame) : PXLActionSheetButtonVerticalPadding; 152 | 153 | [self.otherButtonTitles enumerateObjectsUsingBlock:^(NSString *buttonTitle, NSUInteger idx, BOOL *stop) { 154 | UIButton *newButton = ({ 155 | UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom]; 156 | 157 | if (self.theme.actionSheetStyle == PXLActionSheetStyleRounded) { 158 | button.frame = CGRectMake(PXLActionSheetButtonVerticalPadding, yPos, CGRectGetWidth(view.frame) - (PXLActionSheetButtonHorizontalPadding * 2), PXLActionSheetButtonHeight); 159 | } else { 160 | button.frame = CGRectMake(0, yPos, CGRectGetWidth(view.frame), PXLActionSheetButtonHeight); 161 | } 162 | 163 | [button setTag:idx]; 164 | [button setTitle:buttonTitle forState:UIControlStateNormal]; 165 | [button setTitleColor:self.theme.normalButtonTextColor forState:UIControlStateNormal]; 166 | [button setTitleColor:self.theme.normalButtonHighlightTextColor forState:UIControlStateHighlighted]; 167 | [button setBackgroundColor:self.theme.normalButtonColor forState:UIControlStateNormal]; 168 | [button setBackgroundColor:self.theme.normalButtonHighlightColor forState:UIControlStateHighlighted]; 169 | 170 | button.titleLabel.font = self.theme.buttonFont; 171 | button.layer.masksToBounds = YES; 172 | 173 | NSInteger lastButtonIndex = [self.otherButtonTitles count] - 1; 174 | if (self.theme.actionSheetStyle == PXLActionSheetStyleRounded) { 175 | if (idx == 0) { 176 | [button applyCornerRadiusMaskForCorners:UIRectCornerTopLeft|UIRectCornerTopRight withRadius:self.theme.cornerRadius]; 177 | } else if (idx == lastButtonIndex && !self.destructiveButtonTitle) { 178 | [button applyCornerRadiusMaskForCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight withRadius:self.theme.cornerRadius]; 179 | } else if (lastButtonIndex == 0 && !self.destructiveButtonTitle) { 180 | [button applyCornerRadiusMaskForCorners:UIRectCornerAllCorners withRadius:self.theme.cornerRadius]; 181 | } 182 | } 183 | 184 | if (idx != lastButtonIndex) { 185 | [button addSubview:[self buttonDividerAtYPos:CGRectGetMaxY(button.bounds) - 0.75]]; 186 | } else { 187 | if (self.destructiveButtonTitle) { 188 | [button addSubview:[self buttonDividerAtYPos:CGRectGetMaxY(button.bounds) - 0.75]]; 189 | } 190 | } 191 | 192 | [button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside]; 193 | button; 194 | }); 195 | 196 | [view addSubview:newButton]; 197 | yPos = CGRectGetMaxY(newButton.frame); 198 | }]; 199 | 200 | if (self.destructiveButtonTitle) { 201 | UIButton *newButton = [UIButton buttonWithType:UIButtonTypeCustom]; 202 | 203 | if (self.theme.actionSheetStyle == PXLActionSheetStyleRounded) { 204 | newButton.frame = CGRectMake(PXLActionSheetButtonHorizontalPadding, yPos, CGRectGetWidth(view.frame) - (PXLActionSheetButtonHorizontalPadding * 2), PXLActionSheetButtonHeight); 205 | } else { 206 | newButton.frame = CGRectMake(0, yPos, CGRectGetWidth(view.frame), PXLActionSheetButtonHeight); 207 | } 208 | 209 | [newButton setTag:-2]; 210 | [newButton setTitle:self.destructiveButtonTitle forState:UIControlStateNormal]; 211 | [newButton setTitleColor:self.theme.destructiveButtonTextColor forState:UIControlStateNormal]; 212 | [newButton setTitleColor:self.theme.destructiveButtonHighlightTextColor forState:UIControlStateHighlighted]; 213 | [newButton setBackgroundColor:self.theme.destructiveButtonColor forState:UIControlStateNormal]; 214 | [newButton setBackgroundColor:self.theme.destructiveButtonHighlightColor forState:UIControlStateHighlighted]; 215 | newButton.titleLabel.font = self.theme.buttonFont; 216 | 217 | [newButton addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside]; 218 | newButton.layer.masksToBounds = NO; 219 | 220 | if (self.theme.actionSheetStyle == PXLActionSheetStyleRounded) { 221 | if (self.otherButtonTitles.count > 0) { 222 | [newButton applyCornerRadiusMaskForCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight withRadius:self.theme.cornerRadius]; 223 | } else { 224 | [newButton applyCornerRadiusMaskForCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight|UIRectCornerTopLeft|UIRectCornerTopRight withRadius:self.theme.cornerRadius]; 225 | } 226 | } 227 | 228 | [view addSubview:newButton]; 229 | yPos = CGRectGetMaxY(newButton.frame); 230 | } 231 | 232 | self.cancelButton = ({ 233 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 234 | 235 | if (self.theme.actionSheetStyle == PXLActionSheetStyleRounded) { 236 | button.frame = CGRectMake(PXLActionSheetButtonHorizontalPadding, yPos + PXLActionSheetButtonVerticalPadding, CGRectGetWidth(view.frame) - (PXLActionSheetButtonHorizontalPadding * 2), PXLActionSheetButtonHeight); 237 | } else { 238 | button.frame = CGRectMake(0, yPos + PXLActionSheetButtonVerticalPadding, CGRectGetWidth(view.frame), PXLActionSheetButtonHeight); 239 | } 240 | 241 | [button setTitle:self.cancelButtonTitle forState:UIControlStateNormal]; 242 | [button setTitleColor:self.theme.normalButtonTextColor forState:UIControlStateNormal]; 243 | [button setTitleColor:self.theme.normalButtonHighlightTextColor forState:UIControlStateHighlighted]; 244 | [button setBackgroundColor:self.theme.normalButtonColor forState:UIControlStateNormal]; 245 | [button setBackgroundColor:self.theme.normalButtonHighlightColor forState:UIControlStateHighlighted]; 246 | 247 | button.titleLabel.font = self.theme.buttonFont; 248 | 249 | [button addTarget:self action:@selector(cancelButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 250 | 251 | if (self.theme.actionSheetStyle == PXLActionSheetStyleRounded) { 252 | button.layer.cornerRadius = self.theme.cornerRadius; 253 | button.layer.masksToBounds = YES; 254 | } 255 | 256 | button; 257 | }); 258 | 259 | [view addSubview:self.cancelButton]; 260 | } 261 | 262 | - (UIView *)buttonDividerAtYPos:(CGFloat)yPos { 263 | return ({ 264 | UIView *view = [[UIView alloc] init]; 265 | 266 | if (self.theme.actionSheetStyle == PXLActionSheetStyleRounded) { 267 | view.frame = CGRectMake(0, yPos, CGRectGetWidth(self.containerView.bounds) - (PXLActionSheetButtonHorizontalPadding * 2), 0.75); 268 | } else { 269 | view.frame = CGRectMake(0, yPos, CGRectGetWidth(self.containerView.bounds), 0.75); 270 | } 271 | 272 | view.backgroundColor = self.theme.borderColor; 273 | view; 274 | }); 275 | } 276 | 277 | #pragma mark - Animations 278 | 279 | - (void)showInView:(UIView *)view { 280 | 281 | self.containerView = view; 282 | self.frame = self.containerView.bounds; 283 | 284 | // --- SETUP buttons 285 | _containerSnapShotView = [_containerView snapshotViewAfterScreenUpdates:NO]; 286 | _containerSnapShotView.isAccessibilityElement = YES; 287 | _containerSnapShotView.accessibilityLabel = self.cancelButtonTitle; 288 | [self addSubview:_containerSnapShotView]; 289 | 290 | [_containerSnapShotView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cancelButtonTapped:)]]; 291 | 292 | CGFloat actionSheetHeight = [self heightForActionSheetWithNumberOfButtons:[_otherButtonTitles count]]; 293 | 294 | _actionSheetBackgroundView = ({ 295 | UIView *view = [[UIView alloc] initWithFrame:({ 296 | CGRect frame = self.bounds; 297 | frame.size.width = CGRectGetWidth(_containerView.bounds); 298 | frame.size.height = actionSheetHeight; 299 | frame.origin.x = 0; 300 | frame.origin.y = CGRectGetHeight(_containerView.bounds) - actionSheetHeight; 301 | frame; 302 | })]; 303 | 304 | view.backgroundColor = self.theme.backgroundColor; 305 | view; 306 | }); 307 | 308 | [self addSubview:_actionSheetBackgroundView]; 309 | 310 | if (_title) { 311 | _titleLabel = ({ 312 | UILabel *label = [[UILabel alloc] initWithFrame:({ 313 | CGRect frame = CGRectZero; 314 | frame = CGRectMake(0, 0, CGRectGetWidth(_actionSheetBackgroundView.bounds), [self heightForActionSheetTitleLabel]); 315 | frame; 316 | })]; 317 | 318 | label.text = _title; 319 | label.font = self.theme.titleFont; 320 | label.numberOfLines = 0; 321 | label.textAlignment = NSTextAlignmentCenter; 322 | label.textColor = self.theme.titleTextColor; 323 | 324 | label; 325 | }); 326 | _titleLabel.isAccessibilityElement = YES; 327 | _titleLabel.accessibilityLabel = self.title; 328 | 329 | [_actionSheetBackgroundView addSubview:_titleLabel]; 330 | } 331 | 332 | [self addButtonSubViewsToView:_actionSheetBackgroundView]; 333 | // --- SETUP buttons 334 | 335 | CGRect actionSheetBackgroundViewFinalFrame = self.actionSheetBackgroundView.frame; 336 | 337 | self.actionSheetBackgroundView.frame = CGRectMake(CGRectGetMinX(self.actionSheetBackgroundView.frame), CGRectGetHeight(self.containerView.frame), CGRectGetWidth(self.actionSheetBackgroundView.frame), CGRectGetHeight(self.actionSheetBackgroundView.frame)); 338 | 339 | [self.containerView addSubview:self]; 340 | 341 | [UIView animateWithDuration:self.theme.animationSpeed / 2 animations:^{ 342 | self.containerSnapShotView.layer.opacity = 0.6; 343 | }]; 344 | 345 | [UIView animateWithDuration:self.theme.animationSpeed delay:0 usingSpringWithDamping:self.theme.animationSpringDamping initialSpringVelocity:self.theme.animationSpringVelocity options:kNilOptions animations:^{ 346 | self.actionSheetBackgroundView.frame = actionSheetBackgroundViewFinalFrame; 347 | } completion:^(BOOL finished) { 348 | if (finished) { 349 | self.visibilty = PXLActionSheetVisibilityVisible; 350 | if ([self.delegate respondsToSelector:@selector(actionSheet:didChangeVisibility:)]) { 351 | [self.delegate actionSheet:self didChangeVisibility:self.visibilty]; 352 | } 353 | } 354 | }]; 355 | } 356 | 357 | - (void)dismissFromView:(UIView *)view { 358 | 359 | [UIView animateWithDuration:self.theme.animationSpeed / 4 animations:^{ 360 | self.containerSnapShotView.layer.opacity = 1.0; 361 | self.actionSheetBackgroundView.frame = CGRectMake(CGRectGetMinX(self.actionSheetBackgroundView.frame), CGRectGetHeight(self.containerView.frame), CGRectGetWidth(self.actionSheetBackgroundView.frame), CGRectGetHeight(self.actionSheetBackgroundView.frame)); 362 | } completion:^(BOOL finished) { 363 | if (finished) { 364 | [self removeFromSuperview]; 365 | self.visibilty = PXLActionSheetVisibilityHidden; 366 | if ([self.delegate respondsToSelector:@selector(actionSheet:didChangeVisibility:)]) { 367 | [self.delegate actionSheet:self didChangeVisibility:self.visibilty]; 368 | } 369 | } 370 | }]; 371 | } 372 | 373 | #pragma mark - Helpers 374 | 375 | - (CGFloat)heightForActionSheetTitleLabel { 376 | CGSize maxSize = CGSizeMake(CGRectGetWidth(self.frame), CGFLOAT_MAX); 377 | 378 | CGRect labelRect = [self.title boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName : self.theme.titleFont} context:nil]; 379 | 380 | return CGRectGetHeight(labelRect) + (PXLActionSheetTitlePadding * 2); 381 | } 382 | 383 | - (CGFloat)heightForActionSheetWithNumberOfButtons:(NSInteger)numberOfButtons { 384 | CGFloat height = 0.0f; 385 | 386 | NSInteger initialNumberOfButtons = numberOfButtons; 387 | 388 | numberOfButtons++; // Cancel Button 389 | if (self.destructiveButtonTitle) { 390 | numberOfButtons++; 391 | } 392 | 393 | height += PXLActionSheetButtonHeight * numberOfButtons; 394 | 395 | numberOfButtons = numberOfButtons - initialNumberOfButtons; 396 | 397 | if (! self.destructiveButtonTitle) { 398 | numberOfButtons++; 399 | } 400 | 401 | height += PXLActionSheetButtonVerticalPadding * numberOfButtons; 402 | height += (self.title) ? [self heightForActionSheetTitleLabel] : 0; 403 | 404 | return height; 405 | } 406 | 407 | #pragma mark - Taps 408 | 409 | - (void)cancelButtonTapped:(UITapGestureRecognizer *)sender { 410 | if (self.tapBlock) { 411 | self.tapBlock(self, -1); 412 | } 413 | 414 | [self dismissFromView:self]; 415 | } 416 | 417 | - (void)buttonTapped:(UIButton *)sender { 418 | if (self.tapBlock) { 419 | self.tapBlock(self, sender.tag); 420 | } 421 | 422 | [self dismissFromView:self.containerView]; 423 | } 424 | 425 | @end 426 | -------------------------------------------------------------------------------- /PXLActionSheet/PXLActionSheetTheme.h: -------------------------------------------------------------------------------- 1 | // 2 | // PXLActionSheetTheme.h 3 | // PXLActionSheet 4 | // 5 | // Copyright (c) 2014 Jason Silberman 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | // 25 | 26 | typedef NS_ENUM(NSInteger, PXLActionSheetStyle) { 27 | PXLActionSheetStyleSquared, 28 | PXLActionSheetStyleRounded 29 | }; 30 | 31 | @interface PXLActionSheetTheme : NSObject 32 | 33 | @property (nonatomic, assign) PXLActionSheetStyle actionSheetStyle; 34 | 35 | @property (nonatomic) UIFont *titleFont; 36 | @property (nonatomic) UIFont *buttonFont; 37 | 38 | @property (nonatomic) UIColor *titleTextColor; 39 | @property (nonatomic) UIColor *normalButtonTextColor; 40 | @property (nonatomic) UIColor *destructiveButtonTextColor; 41 | 42 | @property (nonatomic) UIColor *normalButtonHighlightTextColor; 43 | @property (nonatomic) UIColor *destructiveButtonHighlightTextColor; 44 | 45 | @property (nonatomic) UIColor *normalButtonColor; 46 | @property (nonatomic) UIColor *destructiveButtonColor; 47 | 48 | @property (nonatomic) UIColor *normalButtonHighlightColor; 49 | @property (nonatomic) UIColor *destructiveButtonHighlightColor; 50 | 51 | @property (nonatomic, assign) CGFloat cornerRadius; // Only with actionSheetStyleRounded 52 | 53 | @property (nonatomic, assign) CGFloat animationSpeed; 54 | @property (nonatomic, assign) CGFloat animationSpringDamping; 55 | @property (nonatomic, assign) CGFloat animationSpringVelocity; 56 | 57 | @property (nonatomic) UIColor *borderColor; 58 | @property (nonatomic) UIColor *backgroundColor; 59 | @property (nonatomic) UIColor *backdropShadowColor; 60 | 61 | + (instancetype)defaultTheme; 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /PXLActionSheet/PXLActionSheetTheme.m: -------------------------------------------------------------------------------- 1 | // 2 | // PXLActionSheetTheme.m 3 | // PXLActionSheet 4 | // 5 | // Copyright (c) 2014 Jason Silberman 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | // 25 | 26 | #import "PXLActionSheetTheme.h" 27 | 28 | @implementation PXLActionSheetTheme 29 | 30 | + (instancetype)defaultTheme { 31 | PXLActionSheetTheme *theme = [PXLActionSheetTheme new]; 32 | 33 | theme.actionSheetStyle = PXLActionSheetStyleRounded; 34 | 35 | theme.titleFont = [UIFont fontWithName:@"Avenir" size:16]; 36 | theme.buttonFont = [UIFont fontWithName:@"Avenir" size:18]; 37 | 38 | theme.titleTextColor = [UIColor blackColor]; 39 | theme.normalButtonTextColor = [UIColor blackColor]; 40 | theme.destructiveButtonTextColor = [UIColor redColor]; 41 | 42 | theme.normalButtonHighlightTextColor = [UIColor whiteColor]; 43 | theme.destructiveButtonHighlightTextColor = [UIColor whiteColor]; 44 | 45 | theme.normalButtonColor = [UIColor whiteColor]; 46 | theme.destructiveButtonColor = [UIColor whiteColor]; 47 | 48 | theme.normalButtonHighlightColor = [UIColor blackColor]; 49 | theme.destructiveButtonHighlightColor = [UIColor redColor]; 50 | 51 | theme.cornerRadius = 2.0; 52 | 53 | theme.animationSpeed = 0.55; 54 | theme.animationSpringDamping = 0.5; 55 | theme.animationSpringVelocity = 0.3; 56 | 57 | theme.borderColor = [UIColor colorWithWhite:0.0 alpha:0.25]; 58 | theme.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.9]; 59 | theme.backdropShadowColor = [UIColor blackColor]; 60 | 61 | return theme; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | PXLActionSheet 2 | ============== 3 | 4 | A new customizable replacement for UIActionSheet. 5 | 6 | ## Screenshots 7 | 8 | ![Screenshot](https://github.com/jasonsilberman/PXLActionSheet/blob/master/screenshot.png) 9 | 10 | ## Why? 11 | 1. The system `UIActionSheet` are very uncustomizable. 12 | 2. Blocks! Blocks! Blocks! 13 | 14 | ## Documentation 15 | You can check out the documentation over at [Cocoadocs](http://cocoadocs.org/docsets/PXLActionSheet/). 16 | 17 | ## Adding to Your Project 18 | Getting started using PXLActionSheet is really easy! You can use Cocoapods or you can do it manually. 19 | 20 | ### Using CocoaPods 21 | Add the following to your `Podfile`. 22 | 23 | ```ruby 24 | pod 'PXLActionSheet' 25 | ``` 26 | 27 | ### Manually 28 | To manually add to your project: 29 | 30 | 1. Add the files in `PXLActionSheet/` to your project. 31 | 32 | PXLNetworking requires ARC. 33 | 34 | ## Usage 35 | PXLActionSheet is super simple. 36 | 37 | 1. Create a `PXLActionSheetTheme` (or use the defaultTheme). 38 | 2. Create and show a `PXLActionSheet`. 39 | 40 | Here is an example: 41 | 42 | ```objc 43 | [PXLActionSheet showInView:self.view 44 | withTheme:[PXLActionSheetTheme defaultTheme] 45 | title:@"A new customizable replacement for UIActionSheet." 46 | cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil 47 | otherButtonTitles:@[@"Custom Fonts", @"Custom Colors", @"And More!"] 48 | tapBlock:^(PXLActionSheet *actionSheet, NSInteger tappedButtonIndex) { 49 | NSLog(@"tapped at %ld", (long)tappedButtonIndex); 50 | }]; 51 | ``` 52 | 53 | *Super simple, I know!* 54 | 55 | ## License 56 | PXLActionSheet is available under the MIT license. See the LICENSE file for more info. 57 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/implicityhq/PXLActionSheet/13b1aaecf30dd14244f76033eb2e6034edffa919/screenshot.png --------------------------------------------------------------------------------