├── Pods ├── Pods-SDCAutoLayout.xcconfig ├── Pods-SDCAlertViewTests-OCMock.xcconfig ├── Pods-SDCAlertViewTests-SDCAutoLayout.xcconfig ├── Headers │ ├── RBBAnimation │ │ ├── RBBAnimation.h │ │ ├── RBBCubicBezier.h │ │ ├── RBBBlockBasedArray.h │ │ ├── RBBCustomAnimation.h │ │ ├── RBBEasingFunction.h │ │ ├── RBBSpringAnimation.h │ │ ├── RBBTweenAnimation.h │ │ └── RBBLinearInterpolation.h │ └── SDCAutoLayout │ │ └── UIView+SDCAutoLayout.h ├── Pods-RBBAnimation.xcconfig ├── BuildHeaders │ ├── RBBAnimation │ │ ├── RBBAnimation.h │ │ ├── RBBCubicBezier.h │ │ ├── RBBBlockBasedArray.h │ │ ├── RBBCustomAnimation.h │ │ ├── RBBEasingFunction.h │ │ ├── RBBSpringAnimation.h │ │ ├── RBBTweenAnimation.h │ │ └── RBBLinearInterpolation.h │ └── SDCAutoLayout │ │ └── UIView+SDCAutoLayout.h ├── Pods-SDCAlertViewTests-RBBAnimation.xcconfig ├── Pods-RBBAnimation-prefix.pch ├── Pods-SDCAutoLayout-prefix.pch ├── SDCAutoLayout │ ├── README.md │ ├── LICENSE │ └── AutoLayout │ │ ├── UIView+SDCAutoLayout.h │ │ └── UIView+SDCAutoLayout.m ├── Pods-dummy.m ├── Pods-SDCAlertViewTests-OCMock-prefix.pch ├── Pods-SDCAlertViewTests-RBBAnimation-prefix.pch ├── Pods-SDCAlertViewTests-SDCAutoLayout-prefix.pch ├── Pods-RBBAnimation-dummy.m ├── Pods-SDCAutoLayout-dummy.m ├── Pods-SDCAlertViewTests-dummy.m ├── Pods-SDCAlertViewTests-OCMock-dummy.m ├── Pods-SDCAlertViewTests-RBBAnimation-dummy.m ├── Pods-SDCAlertViewTests-SDCAutoLayout-dummy.m ├── Manifest.lock ├── Pods-SDCAutoLayout-Private.xcconfig ├── Pods-RBBAnimation-Private.xcconfig ├── RBBAnimation │ ├── RBBAnimation │ │ ├── RBBCubicBezier.h │ │ ├── RBBCustomAnimation.h │ │ ├── RBBLinearInterpolation.h │ │ ├── RBBTweenAnimation.h │ │ ├── RBBBlockBasedArray.h │ │ ├── RBBAnimation.h │ │ ├── RBBCustomAnimation.m │ │ ├── RBBSpringAnimation.h │ │ ├── RBBAnimation.m │ │ ├── RBBEasingFunction.h │ │ ├── RBBTweenAnimation.m │ │ ├── RBBBlockBasedArray.m │ │ ├── RBBCubicBezier.m │ │ ├── RBBEasingFunction.m │ │ ├── RBBSpringAnimation.m │ │ └── RBBLinearInterpolation.m │ ├── LICENSE │ └── README.md ├── Pods-SDCAlertViewTests-OCMock-Private.xcconfig ├── Pods.xcconfig ├── Pods-SDCAlertViewTests-SDCAutoLayout-Private.xcconfig ├── Pods-SDCAlertViewTests-RBBAnimation-Private.xcconfig ├── Pods-environment.h ├── Pods-SDCAlertViewTests-environment.h ├── Pods-acknowledgements.markdown ├── Pods-SDCAlertViewTests-acknowledgements.markdown ├── Pods-acknowledgements.plist ├── Pods-resources.sh ├── Pods-SDCAlertViewTests-resources.sh └── Pods-SDCAlertViewTests-acknowledgements.plist ├── SDCAlertView ├── en.lproj │ └── InfoPlist.strings ├── SDCViewController.h ├── Source │ ├── SDCIntrinsicallySizedView.h │ ├── SDCAlertViewBackgroundView.h │ ├── SDCAlertViewCoordinator.h │ ├── SDCAlertViewController.h │ ├── SDCIntrinsicallySizedView.m │ ├── SDCAlertViewContentView.h │ ├── SDCAlertViewTransitioning.h │ ├── SDCAlertViewBackgroundView.m │ ├── SDCAlertViewCoordinator.m │ ├── SDCAlertView.h │ ├── SDCAlertViewController.m │ └── SDCAlertView.m ├── SDCAppDelegate.h ├── SDCAlertView-Prefix.pch ├── main.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── SDCAlertView-Info.plist ├── SDCAppDelegate.m ├── SDCViewController.m ├── iPad.storyboard └── Base.lproj │ └── iPhone.storyboard ├── SDCAlertViewTests ├── en.lproj │ └── InfoPlist.strings └── SDCAlertViewTests-Info.plist ├── Podfile ├── SDCAlertView.xcworkspace └── contents.xcworkspacedata ├── SDCAlertView.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── Scott.xcuserdatad │ └── xcschemes │ ├── xcschememanagement.plist │ └── SDCAlertView.xcscheme ├── .gitignore ├── Podfile.lock ├── SDCAlertView.podspec ├── LICENSE ├── CHANGELOG.md └── README.md /Pods/Pods-SDCAutoLayout.xcconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-OCMock.xcconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-SDCAutoLayout.xcconfig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Pods/Headers/RBBAnimation/RBBAnimation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBAnimation.h -------------------------------------------------------------------------------- /Pods/Pods-RBBAnimation.xcconfig: -------------------------------------------------------------------------------- 1 | PODS_RBBANIMATION_OTHER_LDFLAGS = -framework QuartzCore -------------------------------------------------------------------------------- /Pods/BuildHeaders/RBBAnimation/RBBAnimation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBAnimation.h -------------------------------------------------------------------------------- /Pods/Headers/RBBAnimation/RBBCubicBezier.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBCubicBezier.h -------------------------------------------------------------------------------- /SDCAlertView/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Pods/BuildHeaders/RBBAnimation/RBBCubicBezier.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBCubicBezier.h -------------------------------------------------------------------------------- /Pods/Headers/RBBAnimation/RBBBlockBasedArray.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBBlockBasedArray.h -------------------------------------------------------------------------------- /Pods/Headers/RBBAnimation/RBBCustomAnimation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBCustomAnimation.h -------------------------------------------------------------------------------- /Pods/Headers/RBBAnimation/RBBEasingFunction.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBEasingFunction.h -------------------------------------------------------------------------------- /Pods/Headers/RBBAnimation/RBBSpringAnimation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBSpringAnimation.h -------------------------------------------------------------------------------- /Pods/Headers/RBBAnimation/RBBTweenAnimation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBTweenAnimation.h -------------------------------------------------------------------------------- /SDCAlertViewTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "7.0" 2 | 3 | pod "RBBAnimation", '~> 0.3' 4 | pod "SDCAutoLayout", '~> 2.0' -------------------------------------------------------------------------------- /Pods/BuildHeaders/RBBAnimation/RBBBlockBasedArray.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBBlockBasedArray.h -------------------------------------------------------------------------------- /Pods/BuildHeaders/RBBAnimation/RBBCustomAnimation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBCustomAnimation.h -------------------------------------------------------------------------------- /Pods/BuildHeaders/RBBAnimation/RBBEasingFunction.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBEasingFunction.h -------------------------------------------------------------------------------- /Pods/BuildHeaders/RBBAnimation/RBBSpringAnimation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBSpringAnimation.h -------------------------------------------------------------------------------- /Pods/BuildHeaders/RBBAnimation/RBBTweenAnimation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBTweenAnimation.h -------------------------------------------------------------------------------- /Pods/Headers/SDCAutoLayout/UIView+SDCAutoLayout.h: -------------------------------------------------------------------------------- 1 | ../../SDCAutoLayout/AutoLayout/UIView+SDCAutoLayout.h -------------------------------------------------------------------------------- /Pods/BuildHeaders/SDCAutoLayout/UIView+SDCAutoLayout.h: -------------------------------------------------------------------------------- 1 | ../../SDCAutoLayout/AutoLayout/UIView+SDCAutoLayout.h -------------------------------------------------------------------------------- /Pods/Headers/RBBAnimation/RBBLinearInterpolation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBLinearInterpolation.h -------------------------------------------------------------------------------- /Pods/BuildHeaders/RBBAnimation/RBBLinearInterpolation.h: -------------------------------------------------------------------------------- 1 | ../../RBBAnimation/RBBAnimation/RBBLinearInterpolation.h -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-RBBAnimation.xcconfig: -------------------------------------------------------------------------------- 1 | PODS_SDCALERTVIEWTESTS_RBBANIMATION_OTHER_LDFLAGS = -framework QuartzCore -------------------------------------------------------------------------------- /Pods/Pods-RBBAnimation-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-environment.h" 6 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAutoLayout-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-environment.h" 6 | -------------------------------------------------------------------------------- /Pods/SDCAutoLayout/README.md: -------------------------------------------------------------------------------- 1 | SDCAutoLayout 2 | ============= 3 | 4 | A UIView category that simplifies dealing with Auto Layout 5 | -------------------------------------------------------------------------------- /Pods/Pods-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods : NSObject 3 | @end 4 | @implementation PodsDummy_Pods 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-OCMock-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-SDCAlertViewTests-environment.h" 6 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-RBBAnimation-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-SDCAlertViewTests-environment.h" 6 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-SDCAutoLayout-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-SDCAlertViewTests-environment.h" 6 | -------------------------------------------------------------------------------- /Pods/Pods-RBBAnimation-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_RBBAnimation : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_RBBAnimation 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAutoLayout-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SDCAutoLayout : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SDCAutoLayout 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SDCAlertViewTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SDCAlertViewTests 5 | @end 6 | -------------------------------------------------------------------------------- /SDCAlertView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-OCMock-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SDCAlertViewTests_OCMock : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SDCAlertViewTests_OCMock 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-RBBAnimation-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SDCAlertViewTests_RBBAnimation : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SDCAlertViewTests_RBBAnimation 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-SDCAutoLayout-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SDCAlertViewTests_SDCAutoLayout : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SDCAlertViewTests_SDCAutoLayout 5 | @end 6 | -------------------------------------------------------------------------------- /SDCAlertView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | -------------------------------------------------------------------------------- /SDCAlertView/SDCViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCViewController.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 9/20/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SDCViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - RBBAnimation (0.3.0) 3 | - SDCAutoLayout (2.0) 4 | 5 | DEPENDENCIES: 6 | - RBBAnimation (~> 0.3) 7 | - SDCAutoLayout (~> 2.0) 8 | 9 | SPEC CHECKSUMS: 10 | RBBAnimation: e7f31ed62f760f3caf120b5d943267bd9a8e1f64 11 | SDCAutoLayout: fbb30550a36f244223ea40560549372eccd1c4c7 12 | 13 | COCOAPODS: 0.29.0 14 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - RBBAnimation (0.3.0) 3 | - SDCAutoLayout (2.0) 4 | 5 | DEPENDENCIES: 6 | - RBBAnimation (~> 0.3) 7 | - SDCAutoLayout (~> 2.0) 8 | 9 | SPEC CHECKSUMS: 10 | RBBAnimation: e7f31ed62f760f3caf120b5d943267bd9a8e1f64 11 | SDCAutoLayout: fbb30550a36f244223ea40560549372eccd1c4c7 12 | 13 | COCOAPODS: 0.29.0 14 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCIntrinsicallySizedView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCIntrinsicallySizedView.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 3/16/14. 6 | // Copyright (c) 2014 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SDCIntrinsicallySizedView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertViewBackgroundView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertViewBackgroundView.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 11/5/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SDCAlertViewBackgroundView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAutoLayout-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-SDCAutoLayout.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/SDCAutoLayout" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/RBBAnimation" "${PODS_ROOT}/Headers/SDCAutoLayout" 4 | OTHER_LDFLAGS = -ObjC 5 | PODS_ROOT = ${SRCROOT} -------------------------------------------------------------------------------- /Pods/Pods-RBBAnimation-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-RBBAnimation.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/RBBAnimation" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/RBBAnimation" "${PODS_ROOT}/Headers/SDCAutoLayout" 4 | OTHER_LDFLAGS = -ObjC ${PODS_RBBANIMATION_OTHER_LDFLAGS} 5 | PODS_ROOT = ${SRCROOT} -------------------------------------------------------------------------------- /SDCAlertView/SDCAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAppDelegate.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 9/20/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SDCAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBCubicBezier.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBCubicBezier.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RBBTweenAnimation.h" 12 | 13 | extern RBBEasingFunction RBBCubicBezier(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2); -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-OCMock-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-SDCAlertViewTests-OCMock.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/OCMock" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/RBBAnimation" "${PODS_ROOT}/Headers/SDCAutoLayout" 4 | OTHER_LDFLAGS = -ObjC 5 | PODS_ROOT = ${SRCROOT} -------------------------------------------------------------------------------- /Pods/Pods.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/RBBAnimation" "${PODS_ROOT}/Headers/SDCAutoLayout" 3 | OTHER_CFLAGS = $(inherited) "-isystem${PODS_ROOT}/Headers" "-isystem${PODS_ROOT}/Headers/RBBAnimation" "-isystem${PODS_ROOT}/Headers/SDCAutoLayout" 4 | OTHER_LDFLAGS = -ObjC -framework QuartzCore 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBCustomAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBCustomAnimation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/27/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBAnimation.h" 10 | 11 | @interface RBBCustomAnimation : RBBAnimation 12 | 13 | @property (readwrite, nonatomic, copy) RBBAnimationBlock animationBlock; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-SDCAutoLayout-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-SDCAlertViewTests-SDCAutoLayout.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/SDCAutoLayout" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/RBBAnimation" "${PODS_ROOT}/Headers/SDCAutoLayout" 4 | OTHER_LDFLAGS = -ObjC 5 | PODS_ROOT = ${SRCROOT} -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBLinearInterpolation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBLinearInterpolation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/25/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef id (^RBBLinearInterpolation)(CGFloat fraction); 12 | 13 | extern RBBLinearInterpolation RBBInterpolate(NSValue *from, NSValue *to); 14 | -------------------------------------------------------------------------------- /SDCAlertView/SDCAlertView-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 | -------------------------------------------------------------------------------- /SDCAlertView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 9/20/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SDCAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SDCAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertViewCoordinator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertViewCoordinator.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 1/25/14. 6 | // Copyright (c) 2014 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import "SDCAlertViewTransitioning.h" 10 | 11 | @class SDCAlertView; 12 | 13 | @interface SDCAlertViewCoordinator : NSObject 14 | 15 | + (instancetype)sharedCoordinator; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-RBBAnimation-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-SDCAlertViewTests-RBBAnimation.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/RBBAnimation" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/RBBAnimation" "${PODS_ROOT}/Headers/SDCAutoLayout" 4 | OTHER_LDFLAGS = -ObjC ${PODS_SDCALERTVIEWTESTS_RBBANIMATION_OTHER_LDFLAGS} 5 | PODS_ROOT = ${SRCROOT} -------------------------------------------------------------------------------- /SDCAlertView/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 | } -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertViewController.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 11/5/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SDCAlertView; 12 | 13 | @interface SDCAlertViewController : UIViewController 14 | 15 | - (void)replaceAlert:(SDCAlertView *)oldAlert 16 | withAlert:(SDCAlertView *)newAlert 17 | animated:(BOOL)animated 18 | completion:(void(^)(void))completionHandler; 19 | @end 20 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBTweenAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBTweenAnimation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBAnimation.h" 10 | 11 | #import "RBBEasingFunction.h" 12 | 13 | @interface RBBTweenAnimation : RBBAnimation 14 | 15 | @property (readwrite, nonatomic, strong) NSValue *fromValue; 16 | @property (readwrite, nonatomic, strong) NSValue *toValue; 17 | 18 | @property (readwrite, nonatomic, copy) RBBEasingFunction easing; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBBlockBasedArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBBlockBasedArray.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef id (^RBBBlockBasedArrayBlock)(NSUInteger idx); 12 | 13 | @interface RBBBlockBasedArray : NSArray 14 | 15 | + (instancetype)arrayWithCount:(NSUInteger)count block:(RBBBlockBasedArrayBlock)block; 16 | 17 | - (instancetype)initWithCount:(NSUInteger)count block:(RBBBlockBasedArrayBlock)block; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /SDCAlertView/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 | } -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAnimation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/10/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef id (^RBBAnimationBlock)(CGFloat t, CGFloat duration); 12 | 13 | @interface RBBAnimation : CAKeyframeAnimation 14 | 15 | @property (readonly, nonatomic, copy) RBBAnimationBlock animationBlock; 16 | 17 | @end 18 | 19 | @interface RBBAnimation (Unavailable) 20 | 21 | - (void)setValues:(NSArray *)values __attribute__((unavailable("values cannot be set on RBBAnimation"))); 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBCustomAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBCustomAnimation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/27/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBCustomAnimation.h" 10 | 11 | @implementation RBBCustomAnimation 12 | 13 | @synthesize animationBlock = _animationBlock; 14 | 15 | #pragma mark - NSObject 16 | 17 | - (id)copyWithZone:(NSZone *)zone { 18 | RBBCustomAnimation *copy = [super copyWithZone:zone]; 19 | if (copy == nil) return nil; 20 | 21 | copy->_animationBlock = [_animationBlock copy]; 22 | 23 | return copy; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Pods/Pods-environment.h: -------------------------------------------------------------------------------- 1 | 2 | // To check if a library is compiled with CocoaPods you 3 | // can use the `COCOAPODS` macro definition which is 4 | // defined in the xcconfigs so it is available in 5 | // headers also when they are imported in the client 6 | // project. 7 | 8 | 9 | // RBBAnimation 10 | #define COCOAPODS_POD_AVAILABLE_RBBAnimation 11 | #define COCOAPODS_VERSION_MAJOR_RBBAnimation 0 12 | #define COCOAPODS_VERSION_MINOR_RBBAnimation 3 13 | #define COCOAPODS_VERSION_PATCH_RBBAnimation 0 14 | 15 | // SDCAutoLayout 16 | #define COCOAPODS_POD_AVAILABLE_SDCAutoLayout 17 | #define COCOAPODS_VERSION_MAJOR_SDCAutoLayout 2 18 | #define COCOAPODS_VERSION_MINOR_SDCAutoLayout 0 19 | #define COCOAPODS_VERSION_PATCH_SDCAutoLayout 0 20 | 21 | -------------------------------------------------------------------------------- /SDCAlertView.xcodeproj/xcuserdata/Scott.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SDCAlertView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | D25B3CA317ECE7A6004B32A2 16 | 17 | primary 18 | 19 | 20 | D25B3CC417ECE7A6004B32A2 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SDCAlertView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SDCAlertView' 3 | s.version = '1.4.1' 4 | s.license = { :type => 'MIT', :file => 'LICENSE' } 5 | s.authors = { 'Scott Berrevoets' => 's.berrevoets@me.com' } 6 | s.summary = 'SDCAlertView is a UIAlertView clone with added functionality including a contentView property' 7 | s.homepage = 'https://github.com/Scott90/SDCAlertView' 8 | 9 | # Source Info 10 | s.platform = :ios, '7.0' 11 | s.source = { :git => 'https://github.com/Scott90/SDCAlertView.git', :tag => "v#{s.version}" } 12 | s.source_files = 'SDCAlertView/Source/*.{h,m}' 13 | 14 | s.requires_arc = true 15 | 16 | # Pod Dependencies 17 | s.dependency 'SDCAutoLayout', '~> 2.0' 18 | s.dependency 'RBBAnimation', '~> 0.3' 19 | end -------------------------------------------------------------------------------- /SDCAlertViewTests/SDCAlertViewTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.ScottyDoesntCode.${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 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBSpringAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBSpringAnimation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/14/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RBBAnimation.h" 12 | 13 | @interface RBBSpringAnimation : RBBAnimation 14 | 15 | @property (readwrite, nonatomic, assign) CGFloat damping; 16 | @property (readwrite, nonatomic, assign) CGFloat mass; 17 | @property (readwrite, nonatomic, assign) CGFloat stiffness; 18 | @property (readwrite, nonatomic, assign) CGFloat velocity; 19 | 20 | @property (readwrite, nonatomic, strong) NSValue *fromValue; 21 | @property (readwrite, nonatomic, strong) NSValue *toValue; 22 | 23 | @property (readwrite, nonatomic, assign) BOOL allowsOverdamping; 24 | 25 | - (CFTimeInterval)durationForEpsilon:(double)epsilon; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-environment.h: -------------------------------------------------------------------------------- 1 | 2 | // To check if a library is compiled with CocoaPods you 3 | // can use the `COCOAPODS` macro definition which is 4 | // defined in the xcconfigs so it is available in 5 | // headers also when they are imported in the client 6 | // project. 7 | 8 | 9 | // OCMock 10 | #define COCOAPODS_POD_AVAILABLE_OCMock 11 | #define COCOAPODS_VERSION_MAJOR_OCMock 2 12 | #define COCOAPODS_VERSION_MINOR_OCMock 2 13 | #define COCOAPODS_VERSION_PATCH_OCMock 2 14 | 15 | // RBBAnimation 16 | #define COCOAPODS_POD_AVAILABLE_RBBAnimation 17 | #define COCOAPODS_VERSION_MAJOR_RBBAnimation 0 18 | #define COCOAPODS_VERSION_MINOR_RBBAnimation 3 19 | #define COCOAPODS_VERSION_PATCH_RBBAnimation 0 20 | 21 | // SDCAutoLayout 22 | #define COCOAPODS_POD_AVAILABLE_SDCAutoLayout 23 | #define COCOAPODS_VERSION_MAJOR_SDCAutoLayout 2 24 | #define COCOAPODS_VERSION_MINOR_SDCAutoLayout 0 25 | #define COCOAPODS_VERSION_PATCH_SDCAutoLayout 0 26 | 27 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAnimation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/10/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBBlockBasedArray.h" 10 | #import "RBBLinearInterpolation.h" 11 | 12 | #import "RBBAnimation.h" 13 | 14 | @interface RBBAnimation () 15 | 16 | @end 17 | 18 | @implementation RBBAnimation 19 | 20 | #pragma mark - KVO 21 | 22 | + (NSSet *)keyPathsForValuesAffectingValues { 23 | return [NSSet setWithArray:@[ @"animationBlock", @"duration" ]]; 24 | } 25 | 26 | #pragma mark - CAKeyframeAnimation 27 | 28 | - (void)setValues:(NSArray *)values { 29 | return; 30 | } 31 | 32 | - (NSArray *)values { 33 | RBBAnimationBlock block = [self.animationBlock copy]; 34 | 35 | CGFloat duration = self.duration; 36 | 37 | return [RBBBlockBasedArray arrayWithCount:duration * 60 block:^id(NSUInteger idx) { 38 | return block(idx / 60.0, duration); 39 | }]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBEasingFunction.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBEasingFunction.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/14/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef CGFloat (^RBBEasingFunction)(CGFloat t); 12 | 13 | extern RBBEasingFunction const RBBEasingFunctionLinear; 14 | 15 | extern RBBEasingFunction const RBBEasingFunctionEaseInQuad; 16 | extern RBBEasingFunction const RBBEasingFunctionEaseOutQuad; 17 | extern RBBEasingFunction const RBBEasingFunctionEaseInOutQuad; 18 | 19 | extern RBBEasingFunction const RBBEasingFunctionEaseInCubic; 20 | extern RBBEasingFunction const RBBEasingFunctionEaseOutCubic; 21 | extern RBBEasingFunction const RBBEasingFunctionEaseInOutCubic; 22 | 23 | extern RBBEasingFunction const RBBEasingFunctionEaseInQuart; 24 | extern RBBEasingFunction const RBBEasingFunctionEaseOutQuart; 25 | extern RBBEasingFunction const RBBEasingFunctionEaseInOutQuart; 26 | 27 | extern RBBEasingFunction const RBBEasingFunctionEaseInBounce; 28 | extern RBBEasingFunction const RBBEasingFunctionEaseOutBounce; 29 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Robert Böhnke. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /Pods/SDCAutoLayout/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Scott Berrevoets 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Scott Berrevoets 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. -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBTweenAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBTweenAnimation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | 10 | #import "RBBLinearInterpolation.h" 11 | 12 | #import "RBBTweenAnimation.h" 13 | 14 | @implementation RBBTweenAnimation 15 | 16 | #pragma mark - Lifecycle 17 | 18 | - (id)init { 19 | self = [super init]; 20 | if (self == nil) return nil; 21 | 22 | self.easing = RBBEasingFunctionLinear; 23 | 24 | return self; 25 | } 26 | 27 | #pragma mark - KVO 28 | 29 | + (NSSet *)keyPathsForValuesAffectingAnimationBlock { 30 | return [NSSet setWithArray:@[ @"from", @"to", @"easing" ]]; 31 | } 32 | 33 | #pragma mark - RBBAnimation 34 | 35 | - (RBBAnimationBlock)animationBlock { 36 | NSParameterAssert(self.easing != nil); 37 | 38 | RBBEasingFunction easing = [self.easing copy]; 39 | RBBLinearInterpolation lerp = RBBInterpolate(self.fromValue, self.toValue); 40 | 41 | return ^(CGFloat elapsed, CGFloat duration) { 42 | return lerp(easing(elapsed / duration)); 43 | }; 44 | } 45 | 46 | #pragma mark - NSObject 47 | 48 | - (id)copyWithZone:(NSZone *)zone { 49 | RBBTweenAnimation *copy = [super copyWithZone:zone]; 50 | if (copy == nil) return nil; 51 | 52 | copy->_easing = _easing; 53 | 54 | copy->_fromValue = _fromValue; 55 | copy->_toValue = _toValue; 56 | 57 | return copy; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /SDCAlertView/SDCAlertView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.ScottyDoesntCode.${PRODUCT_NAME:rfc1034identifier} 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 | UIMainStoryboardFile 28 | iPhone 29 | UIMainStoryboardFile~ipad 30 | iPad 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBBlockBasedArray.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBBlockBasedArray.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBBlockBasedArray.h" 10 | 11 | @implementation RBBBlockBasedArray { 12 | NSUInteger _count; 13 | RBBBlockBasedArrayBlock _block; 14 | } 15 | 16 | #pragma mark - Lifecycle 17 | 18 | + (instancetype)arrayWithCount:(NSUInteger)count block:(RBBBlockBasedArrayBlock)block { 19 | return [[self alloc] initWithCount:count block:block]; 20 | } 21 | 22 | - (instancetype)initWithCount:(NSUInteger)count block:(RBBBlockBasedArrayBlock)block { 23 | self = [super init]; 24 | if (self == nil) return nil; 25 | 26 | _count = count; 27 | _block = [block copy]; 28 | 29 | return self; 30 | } 31 | 32 | - (instancetype)init { 33 | return [self initWithCount:0 block:nil]; 34 | } 35 | 36 | - (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt { 37 | NSArray *otherArray = [NSArray arrayWithObjects:objects count:cnt]; 38 | 39 | return [self initWithCount:cnt block:^(NSUInteger idx) { 40 | return otherArray[idx]; 41 | }]; 42 | } 43 | 44 | #pragma mark - NSArray primitive methods 45 | 46 | - (NSUInteger)count { 47 | return _count; 48 | } 49 | 50 | - (id)objectAtIndex:(NSUInteger)index { 51 | return _block(index); 52 | } 53 | 54 | #pragma mark - NSObject 55 | 56 | - (id)copyWithZone:(NSZone *)zone { 57 | return [[self.class allocWithZone:zone] initWithCount:_count block:_block]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCIntrinsicallySizedView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDCIntrinsicallySizedView.m 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 3/16/14. 6 | // Copyright (c) 2014 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import "SDCIntrinsicallySizedView.h" 10 | 11 | @implementation SDCIntrinsicallySizedView 12 | 13 | - (CGSize)intrinsicContentSize { 14 | __block CGFloat minX = CGFLOAT_MAX; 15 | __block CGFloat maxX = CGFLOAT_MIN; 16 | __block CGFloat minY = CGFLOAT_MAX; 17 | __block CGFloat maxY = CGFLOAT_MIN; 18 | 19 | [[self subviews] enumerateObjectsUsingBlock:^(UIView *subview, NSUInteger idx, BOOL *stop) { 20 | // Ignore _UILayoutGuide 21 | if (![subview conformsToProtocol:@protocol(UILayoutSupport)]) { 22 | // We could use CGRectGet(Min|Max)(X|Y) using the subview.frame, but subview.frame is undefined when a transform is applied. This calculation is transform-friendly. 23 | minX = MIN(minX, subview.center.x - CGRectGetWidth(subview.bounds) / 2); 24 | maxX = MAX(maxX, subview.center.x + CGRectGetWidth(subview.bounds) / 2); 25 | minY = MIN(minY, subview.center.y - CGRectGetHeight(subview.bounds) / 2); 26 | maxY = MAX(maxY, subview.center.y + CGRectGetHeight(subview.bounds) / 2); 27 | } 28 | }]; 29 | 30 | // If minX is still set to CGFLOAT_MAX, there were no subviews, so just return super's intrinsicContentSize 31 | if (minX == CGFLOAT_MAX) 32 | return [super intrinsicContentSize]; 33 | 34 | return CGSizeMake(maxX - minX, maxY - minY); 35 | } 36 | 37 | - (void)layoutSubviews { 38 | [super layoutSubviews]; 39 | [self invalidateIntrinsicContentSize]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBCubicBezier.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBCubicBezier.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBCubicBezier.h" 10 | 11 | #define A(a1, a2) (1.0 - 3.0 * a2 + 3.0 * a1) 12 | #define B(a1, a2) (3.0 * a2 - 6.0 * a1) 13 | #define C(a1) (3.0 * a1) 14 | 15 | CGFloat RBBCubicBezierCalculate(CGFloat t, CGFloat a1, CGFloat a2) { 16 | return ((A(a1, a2) * t + B(a1, a2)) * t + C(a1)) * t; 17 | } 18 | 19 | CGFloat RBBCubicBezierSlope(CGFloat t, CGFloat a1, CGFloat a2) { 20 | return 3.0 * A(a1, a2) * t * t + 2.0 * B(a1, a2) * t + C(a1); 21 | } 22 | 23 | CGFloat RBBCubicBezierBinarySubdivide(CGFloat x, CGFloat x1, CGFloat x2) { 24 | CGFloat epsilon = 0.0000001; 25 | NSUInteger maxIterations = 10; 26 | 27 | CGFloat start = 0; 28 | CGFloat end = 1; 29 | 30 | CGFloat currentX; 31 | CGFloat currentT; 32 | 33 | NSUInteger i = 0; 34 | do { 35 | currentT = start + (end - start) / 2; 36 | currentX = RBBCubicBezierCalculate(currentT, x1, x2) - x; 37 | 38 | if (currentX > 0) { 39 | end = currentT; 40 | } else { 41 | start = currentT; 42 | } 43 | 44 | } while (fabs(currentX) > epsilon && ++i < maxIterations); 45 | 46 | return currentT; 47 | } 48 | 49 | extern RBBEasingFunction RBBCubicBezier(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) { 50 | if (x1 == y1 && x2 == y2) return RBBEasingFunctionLinear; 51 | 52 | return ^(CGFloat x) { 53 | CGFloat t = RBBCubicBezierBinarySubdivide(x, x1, x2); 54 | 55 | return RBBCubicBezierCalculate(t, y1, y2); 56 | }; 57 | } -------------------------------------------------------------------------------- /SDCAlertView/SDCAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAppDelegate.m 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 9/20/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import "SDCAppDelegate.h" 10 | 11 | @implementation SDCAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // 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. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // 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. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /SDCAlertView.xcodeproj/xcuserdata/Scott.xcuserdatad/xcschemes/SDCAlertView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 35 | 36 | 42 | 43 | 44 | 45 | 46 | 47 | 53 | 54 | 56 | 57 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Pods/Pods-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## RBBAnimation 5 | 6 | Copyright (c) 2013 Robert Böhnke. 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of 9 | this software and associated documentation files (the "Software"), to deal in 10 | the Software without restriction, including without limitation the rights to 11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 12 | the Software, and to permit persons to whom the Software is furnished to do so, 13 | subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | ## SDCAutoLayout 27 | 28 | Copyright (c) 2013 Scott Berrevoets 29 | 30 | Permission is hereby granted, free of charge, to any person obtaining 31 | a copy of this software and associated documentation files (the 32 | "Software"), to deal in the Software without restriction, including 33 | without limitation the rights to use, copy, modify, merge, publish, 34 | distribute, sublicense, and/or sell copies of the Software, and to 35 | permit persons to whom the Software is furnished to do so, subject to 36 | the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be 39 | included in all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 42 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 43 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 44 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 45 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 46 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 47 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 48 | Generated by CocoaPods - http://cocoapods.org 49 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBEasingFunction.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBEasingFunction.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/14/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBEasingFunction.h" 10 | 11 | #if CGFLOAT_IS_DOUBLE 12 | #define POW(X, Y) pow(X, Y) 13 | #else 14 | #define POW(X, Y) powf(X, Y) 15 | #endif 16 | 17 | RBBEasingFunction const RBBEasingFunctionLinear = ^(CGFloat t) { 18 | return t; 19 | }; 20 | 21 | RBBEasingFunction const RBBEasingFunctionEaseInQuad = ^(CGFloat t) { 22 | return t * t; 23 | }; 24 | 25 | RBBEasingFunction const RBBEasingFunctionEaseOutQuad = ^(CGFloat t) { 26 | return t * (2 - t); 27 | }; 28 | 29 | RBBEasingFunction const RBBEasingFunctionEaseInOutQuad = ^(CGFloat t) { 30 | if (t < 0.5) { 31 | return 2 * t * t; 32 | } else { 33 | return -1 + (4 - 2 * t) * t; 34 | } 35 | }; 36 | 37 | RBBEasingFunction const RBBEasingFunctionEaseInCubic = ^(CGFloat t) { 38 | return t * t * t; 39 | }; 40 | 41 | RBBEasingFunction const RBBEasingFunctionEaseOutCubic = ^(CGFloat t) { 42 | return POW(t - 1, 3) + 1; 43 | }; 44 | 45 | RBBEasingFunction const RBBEasingFunctionEaseInOutCubic = ^(CGFloat t) { 46 | if (t < 0.5) { 47 | return 4 * POW(t, 3); 48 | } else { 49 | return (t - 1) * POW(2 * t - 2, 2) + 1; 50 | } 51 | }; 52 | 53 | RBBEasingFunction const RBBEasingFunctionEaseInQuart = ^(CGFloat t) { 54 | return t * t * t * t; 55 | }; 56 | 57 | RBBEasingFunction const RBBEasingFunctionEaseOutQuart = ^(CGFloat t) { 58 | return POW(t - 1, 4) + 1; 59 | }; 60 | 61 | RBBEasingFunction const RBBEasingFunctionEaseInOutQuart = ^(CGFloat t) { 62 | if (t < 0.5) { 63 | return 8 * POW(t, 4); 64 | } else { 65 | return -1 / 2 * POW(2 * t - 2, 4) + 1; 66 | } 67 | }; 68 | 69 | RBBEasingFunction const RBBEasingFunctionEaseInBounce = ^CGFloat(CGFloat t) { 70 | return 1.0 - RBBEasingFunctionEaseOutBounce(1.0 - t); 71 | }; 72 | 73 | RBBEasingFunction const RBBEasingFunctionEaseOutBounce = ^CGFloat(CGFloat t) { 74 | if (t < 4.0 / 11.0) { 75 | return POW(11.0 / 4.0, 2) * POW(t, 2); 76 | } 77 | 78 | if (t < 8.0 / 11.0) { 79 | return 3.0 / 4.0 + POW(11.0 / 4.0, 2) * POW(t - 6.0 / 11.0, 2); 80 | } 81 | 82 | if (t < 10.0 / 11.0) { 83 | return 15.0 /16.0 + POW(11.0 / 4.0, 2) * POW(t - 9.0 / 11.0, 2); 84 | } 85 | 86 | return 63.0 / 64.0 + POW(11.0 / 4.0, 2) * POW(t - 21.0 / 22.0, 2); 87 | }; 88 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertViewContentView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertViewContentView.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 11/5/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SDCAlertView.h" // Required for SDCAlertViewStyle 12 | 13 | @class SDCAlertViewContentView; 14 | 15 | @protocol SDCAlertViewContentViewDelegate 16 | - (void)alertContentView:(SDCAlertViewContentView *)sender didTapButtonAtIndex:(NSUInteger)index; 17 | - (BOOL)alertContentView:(SDCAlertViewContentView *)sender shouldDeselectButtonAtIndex:(NSUInteger)index; 18 | @end 19 | 20 | @interface SDCAlertViewContentView : UIView 21 | 22 | @property (nonatomic, copy) NSString *title; 23 | @property (nonatomic, copy) NSAttributedString *attributedTitle; 24 | @property (nonatomic, copy) NSString *message; 25 | @property (nonatomic, copy) NSAttributedString *attributedMessage; 26 | 27 | @property (nonatomic, readonly) NSArray *textFields; 28 | @property (nonatomic, strong) UIView *customContentView; 29 | 30 | @property (nonatomic, readonly) NSInteger numberOfButtons; 31 | @property (nonatomic) NSInteger cancelButtonIndex; 32 | @property (nonatomic, copy) NSString *cancelButtonTitle; 33 | @property (nonatomic, readonly) NSInteger firstOtherButtonIndex; 34 | @property (nonatomic, getter = isFirstOtherButtonEnabled) BOOL firstOtherButtonEnabled; 35 | @property (nonatomic) BOOL alwaysShowsButtonsVertically; 36 | 37 | @property (nonatomic) CGSize maximumSize; 38 | 39 | @property (nonatomic, weak) id delegate; 40 | 41 | - (instancetype)initWithDelegate:(id )delegate; 42 | 43 | - (void)updateContentForStyle:(SDCAlertViewStyle)style; 44 | - (void)prepareForShowing; 45 | 46 | - (NSInteger)addButtonWithTitle:(NSString *)buttonTitle; 47 | - (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex; 48 | 49 | /* 50 | * Appearance properties 51 | */ 52 | 53 | @property (nonatomic, strong) UIFont *titleLabelFont; 54 | @property (nonatomic, strong) UIColor *titleLabelTextColor; 55 | @property (nonatomic, strong) UIFont *messageLabelFont; 56 | @property (nonatomic, strong) UIColor *messageLabelTextColor; 57 | @property (nonatomic, strong) UIFont *textFieldFont; 58 | @property (nonatomic, strong) UIColor *textFieldTextColor; 59 | @property (nonatomic, strong) UIFont *suggestedButtonFont; 60 | @property (nonatomic, strong) UIFont *normalButtonFont; 61 | @property (nonatomic, strong) UIColor *buttonTextColor; 62 | 63 | @end -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertViewTransitioning.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertViewTransitioning.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 4/11/14. 6 | // Copyright (c) 2014 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import "SDCAlertView.h" 10 | 11 | /** 12 | * The \c SDCAlertViewTransitioning protocol can be used to define custom ways of transitioning between alerts. This 13 | * allows implementers to use different presenting or dismissing animations, change the modality of an alert, etc. 14 | */ 15 | @protocol SDCAlertViewTransitioning 16 | 17 | /** 18 | * The alert that's currently visible on the screen, or \c nil if there are no visible alerts. Currently, only one alert 19 | * can be visible at a time. An alert that's being presented or dismissed is not considered visible. 20 | * 21 | * Most implementers will benefit from making this a private readwrite property that's set from \c presentAlert: and 22 | * \c -dismissAlert:withButtonIndex:animated:. 23 | */ 24 | @property (nonatomic, weak, readonly) SDCAlertView *visibleAlert; 25 | 26 | /** 27 | * Present \c alert on the screen. In this method, add the alert as a subview to some other view and apply the animations 28 | * you want (can be UIView-based or Core Animation), if any. 29 | * 30 | * At the beginning of this method, right before the view actually gets added to a subview, send it \c -willBePresented. 31 | * After all animations have finished, send it \c -wasPresented. These method calls are required so that the appropriate 32 | * \c SDCAlertView delegate methods are called. 33 | */ 34 | - (void)presentAlert:(SDCAlertView *)alert; 35 | 36 | /** 37 | * Remove \c alert from the screen with \c buttonIndex. Before the alert starts animating (or is simply being removed 38 | * if \c animated is \c NO), send it \c -willBeDismissedWithButtonIndex:. When the animations have finished, be sure to 39 | * remove the alert from its superview and send it \c -wasDismissedWithButtonIndex:. 40 | */ 41 | - (void)dismissAlert:(SDCAlertView *)alert withButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated; 42 | @end 43 | 44 | 45 | @interface SDCAlertView (SDCAlertViewTransitioning) 46 | /** 47 | * The transition coordinator to use for presenting and dismissing alerts. Defaults to the SDCAlertViewCoordinator 48 | * singleton if not set to something else. 49 | */ 50 | @property (nonatomic, strong) id transitionCoordinator; 51 | 52 | /* 53 | * The methods below are only to be called from the transitionCoordinator (see above) when a transition is about to happen 54 | * or has just finished. Don't call these methods from anywhere else. 55 | */ 56 | 57 | - (void)willBePresented; 58 | - (void)wasPresented; 59 | 60 | - (void)willBeDismissedWithButtonIndex:(NSInteger)buttonIndex; 61 | - (void)wasDismissedWithButtonIndex:(NSInteger)buttonIndex; 62 | @end 63 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## OCMock 5 | 6 | Copyright (c) 2004-2013 by Mulle Kybernetik. All rights reserved. 7 | 8 | Permission to use, copy, modify and distribute this software and its documentation 9 | is hereby granted, provided that both the copyright notice and this permission 10 | notice appear in all copies of the software, derivative works or modified versions, 11 | and any portions thereof, and that both notices appear in supporting documentation, 12 | and that credit is given to Mulle Kybernetik in all documents and publicity 13 | pertaining to direct or indirect use of this code or its derivatives. 14 | 15 | THIS IS EXPERIMENTAL SOFTWARE AND IT IS KNOWN TO HAVE BUGS, SOME OF WHICH MAY HAVE 16 | SERIOUS CONSEQUENCES. THE COPYRIGHT HOLDER ALLOWS FREE USE OF THIS SOFTWARE IN ITS 17 | "AS IS" CONDITION. THE COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY 18 | DAMAGES WHATSOEVER RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE 19 | OR OF ANY DERIVATIVE WORK. 20 | 21 | 22 | ## RBBAnimation 23 | 24 | Copyright (c) 2013 Robert Böhnke. 25 | 26 | Permission is hereby granted, free of charge, to any person obtaining a copy of 27 | this software and associated documentation files (the "Software"), to deal in 28 | the Software without restriction, including without limitation the rights to 29 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 30 | the Software, and to permit persons to whom the Software is furnished to do so, 31 | subject to the following conditions: 32 | 33 | The above copyright notice and this permission notice shall be included in all 34 | copies or substantial portions of the Software. 35 | 36 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 37 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 38 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 39 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 40 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 41 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 42 | 43 | 44 | ## SDCAutoLayout 45 | 46 | Copyright (c) 2013 Scott Berrevoets 47 | 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of this software and associated documentation files (the 50 | "Software"), to deal in the Software without restriction, including 51 | without limitation the rights to use, copy, modify, merge, publish, 52 | distribute, sublicense, and/or sell copies of the Software, and to 53 | permit persons to whom the Software is furnished to do so, subject to 54 | the following conditions: 55 | 56 | The above copyright notice and this permission notice shall be 57 | included in all copies or substantial portions of the Software. 58 | 59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 60 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 61 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 62 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 63 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 64 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 65 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 66 | Generated by CocoaPods - http://cocoapods.org 67 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBSpringAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBSpringAnimation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/14/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBBlockBasedArray.h" 10 | #import "RBBLinearInterpolation.h" 11 | 12 | #import "RBBSpringAnimation.h" 13 | 14 | @implementation RBBSpringAnimation 15 | 16 | #pragma mark - Lifecycle 17 | 18 | - (id)init { 19 | self = [super init]; 20 | if (self == nil) return nil; 21 | 22 | self.damping = 10; 23 | self.mass = 1; 24 | self.stiffness = 100; 25 | 26 | return self; 27 | } 28 | 29 | #pragma mark - KVO 30 | 31 | + (NSSet *)keyPathsForValuesAffectingAnimationBlock { 32 | return [NSSet setWithArray:@[ @"damping", @"mass", @"stiffness", @"velocity", @"from", @"to", @"allowsOverdamping" ]]; 33 | } 34 | 35 | #pragma mark - RBBSpringAnimation 36 | 37 | - (CFTimeInterval)durationForEpsilon:(double)epsilon { 38 | CGFloat beta = self.damping / (2 * self.mass); 39 | 40 | CFTimeInterval duration = 0; 41 | while (expf(-beta * duration) >= epsilon) { 42 | duration += 0.1; 43 | } 44 | 45 | return duration; 46 | } 47 | 48 | #pragma mark - RBBAnimation 49 | 50 | - (RBBAnimationBlock)animationBlock { 51 | CGFloat b = self.damping; 52 | CGFloat m = self.mass; 53 | CGFloat k = self.stiffness; 54 | CGFloat v0 = self.velocity; 55 | 56 | NSParameterAssert(m > 0); 57 | NSParameterAssert(k > 0); 58 | NSParameterAssert(b > 0); 59 | 60 | CGFloat beta = b / (2 * m); 61 | CGFloat omega0 = sqrtf(k / m); 62 | CGFloat omega1 = sqrtf((omega0 * omega0) - (beta * beta)); 63 | CGFloat omega2 = sqrtf((beta * beta) - (omega0 * omega0)); 64 | 65 | CGFloat x0 = -1; 66 | 67 | if (!self.allowsOverdamping && beta > omega0) beta = omega0; 68 | 69 | CGFloat (^oscillation)(CGFloat); 70 | if (beta < omega0) { 71 | // Underdamped 72 | oscillation = ^(CGFloat t) { 73 | CGFloat envelope = expf(-beta * t); 74 | 75 | return -x0 + envelope * (x0 * cosf(omega1 * t) + ((beta * x0 + v0) / omega1) * sinf(omega1 * t)); 76 | }; 77 | } else if (beta == omega0) { 78 | // Critically damped 79 | oscillation = ^(CGFloat t) { 80 | CGFloat envelope = expf(-beta * t); 81 | 82 | return -x0 + envelope * (x0 + (beta * x0 + v0) * t); 83 | }; 84 | } else { 85 | // Overdamped 86 | oscillation = ^(CGFloat t) { 87 | CGFloat envelope = expf(-beta * t); 88 | 89 | return -x0 + envelope * (x0 * coshf(omega2 * t) + ((beta * x0 + v0) / omega2) * sinhf(omega2 * t)); 90 | }; 91 | } 92 | 93 | RBBLinearInterpolation lerp = RBBInterpolate(self.fromValue, self.toValue); 94 | return ^(CGFloat t, CGFloat _) { 95 | return lerp(oscillation(t)); 96 | }; 97 | } 98 | 99 | #pragma mark - NSObject 100 | 101 | - (id)copyWithZone:(NSZone *)zone { 102 | RBBSpringAnimation *copy = [super copyWithZone:zone]; 103 | if (copy == nil) return nil; 104 | 105 | copy->_damping = _damping; 106 | copy->_mass = _mass; 107 | copy->_stiffness = _stiffness; 108 | copy->_velocity = _velocity; 109 | 110 | copy->_fromValue = _fromValue; 111 | copy->_toValue = _toValue; 112 | 113 | copy->_allowsOverdamping = _allowsOverdamping; 114 | 115 | return copy; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /Pods/Pods-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2013 Robert Böhnke. 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy of 20 | this software and associated documentation files (the "Software"), to deal in 21 | the Software without restriction, including without limitation the rights to 22 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 23 | the Software, and to permit persons to whom the Software is furnished to do so, 24 | subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in all 27 | copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 31 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 32 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 33 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 34 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 | 36 | Title 37 | RBBAnimation 38 | Type 39 | PSGroupSpecifier 40 | 41 | 42 | FooterText 43 | Copyright (c) 2013 Scott Berrevoets 44 | 45 | Permission is hereby granted, free of charge, to any person obtaining 46 | a copy of this software and associated documentation files (the 47 | "Software"), to deal in the Software without restriction, including 48 | without limitation the rights to use, copy, modify, merge, publish, 49 | distribute, sublicense, and/or sell copies of the Software, and to 50 | permit persons to whom the Software is furnished to do so, subject to 51 | the following conditions: 52 | 53 | The above copyright notice and this permission notice shall be 54 | included in all copies or substantial portions of the Software. 55 | 56 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 57 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 58 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 59 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 60 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 61 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 62 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 63 | Title 64 | SDCAutoLayout 65 | Type 66 | PSGroupSpecifier 67 | 68 | 69 | FooterText 70 | Generated by CocoaPods - http://cocoapods.org 71 | Title 72 | 73 | Type 74 | PSGroupSpecifier 75 | 76 | 77 | StringsTable 78 | Acknowledgements 79 | Title 80 | Acknowledgements 81 | 82 | 83 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## 1.4.1 4 | 5 | **Bug Fixes:** 6 | - Show the button top separator in an alert without title or message text (#40) 7 | - Initialization is written a little differently to be more subclass-friendly 8 | - Ready for use in iOS 8 9 | 10 | Though the alert can still be used in iOS 8, keep in mind that the actual iOS 8 alert looks slightly different. The plan is to eventually have support for both, but that's currently not the case. 11 | 12 | ## 1.4 13 | 14 | **What's New:** 15 | - Added the ability to position a two-button alert vertically as opposed to horizontally (#29) 16 | - Added `attributedTitle` and `attributedMessage` properties (#30) 17 | 18 | **Bug Fixes:** 19 | - Auto-layout doesn't complain anymore when using `[[SDCAlertView alloc] init]` 20 | - Fixes a bug that would not show correct button titles in certain alert configurations (#32) 21 | - Instead of clipping button text, it now reduces the size of text on buttons appropriately (#33) 22 | 23 | ## 1.3 24 | 25 | **What's New:** 26 | - The `SDCAlertViewTransitioning` protocol allows users to customize alert transitions and behavior 27 | - `SDCAlertView` now supports `tintColor` for buttons and `contentView` 28 | 29 | **Bug Fixes:** 30 | - Fixes an issue where the status bar style would not be preserved if it was set to `UIStatusBarStyleLightContent` (#26 & #27) 31 | - Fixes a bug that causes the app to lock up due to a race condition (#28) 32 | - Adding subviews to `contentView` won't have any animation-related side effects anymore (see #25) 33 | 34 | ## 1.2.1 35 | 36 | **Bug Fixes:** 37 | - Resolves an issue that could put an app in a bad state when transitioning to and from multiple alerts in rapid succession. 38 | 39 | ## 1.2 40 | 41 | **What's New:** 42 | - New convenience methods for showing alerts more easily 43 | - The `SDCAlertViewWidth` constant is made public (#24) 44 | - The `contentView` does not require vertical constraints anymore, though they can be used to size the `contentView` other than "hug its subviews" (#23) 45 | 46 | **Bug Fixes:** 47 | - Resolves an issue that would show the status bar if it was previously hidden (#21) 48 | - Resolves an issue that would sometimes return the wrong button index when using `addButtonWithTitle:` (c4af94542253e211bebcb17e9a9dc898a284a209) 49 | - Transitions between alerts flow more logically if you call several show or dismiss methods right after each other (#25) 50 | - The `animated` argument in `dismissWithClickedButtonIndex:animated:` is honored again (1bfa04903ffae880a377b3d97ddfed72ad7ff413) 51 | 52 | ## 1.1 53 | 54 | **What's New:** 55 | Support for styling an alert. A number of properties have been exposed so that alerts can be easily given a different style. Styling all alerts in an app using `UIAppearance` is also supported. 56 | 57 | **Bug Fixes:** 58 | - The alert's background is no longer using the toolbar hack (#16 & #17—thanks @clstroud!) 59 | - Accessing a text field before calling `show` does not cause a crash anymore (#14) 60 | - The color of text on a button color did not match `UIAlertView`'s text color 100% 61 | - A disabled button will have its label's `enabled` property set to `NO`, which is also where it gets its gray color from 62 | - A 1px hairline at the bottom of the right button in a two-button alert was removed 63 | 64 | ## 1.0 65 | 66 | This release marks the first official release of SDCAlertView. 67 | 68 | SDCAlertView's behavior should now match UIAlertView's. Any behavior that's different from UIAlertView and is not documented as a "won't fix" or known bug is considered a bug that needs to be solved. 69 | 70 | ## 0.9 71 | 72 | Initial release -------------------------------------------------------------------------------- /Pods/Pods-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 5 | > "$RESOURCES_TO_COPY" 6 | 7 | install_resource() 8 | { 9 | case $1 in 10 | *.storyboard) 11 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 12 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 13 | ;; 14 | *.xib) 15 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 16 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 17 | ;; 18 | *.framework) 19 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 21 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 22 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 23 | ;; 24 | *.xcdatamodel) 25 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 26 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 27 | ;; 28 | *.xcdatamodeld) 29 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 30 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 31 | ;; 32 | *.xcassets) 33 | ;; 34 | /*) 35 | echo "$1" 36 | echo "$1" >> "$RESOURCES_TO_COPY" 37 | ;; 38 | *) 39 | echo "${PODS_ROOT}/$1" 40 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 41 | ;; 42 | esac 43 | } 44 | 45 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 46 | if [[ "${ACTION}" == "install" ]]; then 47 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 48 | fi 49 | rm -f "$RESOURCES_TO_COPY" 50 | 51 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ `xcrun --find actool` ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ] 52 | then 53 | case "${TARGETED_DEVICE_FAMILY}" in 54 | 1,2) 55 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 56 | ;; 57 | 1) 58 | TARGET_DEVICE_ARGS="--target-device iphone" 59 | ;; 60 | 2) 61 | TARGET_DEVICE_ARGS="--target-device ipad" 62 | ;; 63 | *) 64 | TARGET_DEVICE_ARGS="--target-device mac" 65 | ;; 66 | esac 67 | find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 68 | fi 69 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 5 | > "$RESOURCES_TO_COPY" 6 | 7 | install_resource() 8 | { 9 | case $1 in 10 | *.storyboard) 11 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 12 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 13 | ;; 14 | *.xib) 15 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 16 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 17 | ;; 18 | *.framework) 19 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 21 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 22 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 23 | ;; 24 | *.xcdatamodel) 25 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 26 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 27 | ;; 28 | *.xcdatamodeld) 29 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 30 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 31 | ;; 32 | *.xcassets) 33 | ;; 34 | /*) 35 | echo "$1" 36 | echo "$1" >> "$RESOURCES_TO_COPY" 37 | ;; 38 | *) 39 | echo "${PODS_ROOT}/$1" 40 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 41 | ;; 42 | esac 43 | } 44 | 45 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 46 | if [[ "${ACTION}" == "install" ]]; then 47 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 48 | fi 49 | rm -f "$RESOURCES_TO_COPY" 50 | 51 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ `xcrun --find actool` ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ] 52 | then 53 | case "${TARGETED_DEVICE_FAMILY}" in 54 | 1,2) 55 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 56 | ;; 57 | 1) 58 | TARGET_DEVICE_ARGS="--target-device iphone" 59 | ;; 60 | 2) 61 | TARGET_DEVICE_ARGS="--target-device ipad" 62 | ;; 63 | *) 64 | TARGET_DEVICE_ARGS="--target-device mac" 65 | ;; 66 | esac 67 | find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 68 | fi 69 | -------------------------------------------------------------------------------- /Pods/SDCAutoLayout/AutoLayout/UIView+SDCAutoLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SDCAutoLayout.h 3 | // AutoLayout 4 | // 5 | // Created by Scott Berrevoets on 10/18/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | FOUNDATION_EXPORT CGFloat const SDCAutoLayoutStandardSiblingDistance; 12 | FOUNDATION_EXPORT CGFloat const SDCAutoLayoutStandardParentChildDistance; 13 | 14 | @interface UIView (SDCAutoLayout) 15 | 16 | // Helper method that returns the first common ancestor of self and view 17 | - (UIView *)sdc_commonAncestorWithView:(UIView *)view; 18 | 19 | // Aligning a view's edges with its superview 20 | - (NSArray *)sdc_alignEdgesWithSuperview:(UIRectEdge)edges; 21 | - (NSArray *)sdc_alignEdgesWithSuperview:(UIRectEdge)edges insets:(UIEdgeInsets)insets; 22 | 23 | // Aligning a view's edges with another view 24 | - (NSArray *)sdc_alignEdges:(UIRectEdge)edges withView:(UIView *)view; 25 | - (NSArray *)sdc_alignEdges:(UIRectEdge)edges withView:(UIView *)view insets:(UIEdgeInsets)insets; 26 | 27 | - (NSLayoutConstraint *)sdc_alignEdge:(UIRectEdge)edge withEdge:(UIRectEdge)otherEdge ofView:(UIView *)view; 28 | - (NSLayoutConstraint *)sdc_alignEdge:(UIRectEdge)edge withEdge:(UIRectEdge)otherEdge ofView:(UIView *)view inset:(CGFloat)inset; 29 | 30 | // Aligning a view's center with another view 31 | - (NSArray *)sdc_alignCentersWithView:(UIView *)view; 32 | - (NSArray *)sdc_alignCentersWithView:(UIView *)view offset:(UIOffset)offset; 33 | - (NSLayoutConstraint *)sdc_alignHorizontalCenterWithView:(UIView *)view; 34 | - (NSLayoutConstraint *)sdc_alignHorizontalCenterWithView:(UIView *)view offset:(CGFloat)offset; 35 | - (NSLayoutConstraint *)sdc_alignVerticalCenterWithView:(UIView *)view; 36 | - (NSLayoutConstraint *)sdc_alignVerticalCenterWithView:(UIView *)view offset:(CGFloat)offset; 37 | 38 | // Centering a view in its superview 39 | - (NSArray *)sdc_centerInSuperview; 40 | - (NSArray *)sdc_centerInSuperviewWithOffset:(UIOffset)offset; 41 | - (NSLayoutConstraint *)sdc_horizontallyCenterInSuperview; 42 | - (NSLayoutConstraint *)sdc_horizontallyCenterInSuperviewWithOffset:(CGFloat)offset; 43 | - (NSLayoutConstraint *)sdc_verticallyCenterInSuperview; 44 | - (NSLayoutConstraint *)sdc_verticallyCenterInSuperviewWithOffset:(CGFloat)offset; 45 | 46 | // Align a view's baseline with another view 47 | - (NSLayoutConstraint *)sdc_alignBaselineWithView:(UIView *)view; 48 | - (NSLayoutConstraint *)sdc_alignBaselineWithView:(UIView *)view offset:(CGFloat)offset; 49 | 50 | // Pinning a view's dimensions with constants 51 | - (NSLayoutConstraint *)sdc_pinWidth:(CGFloat)width; 52 | 53 | - (NSLayoutConstraint *)sdc_setMinimumWidth:(CGFloat)minimumWidth; 54 | - (NSLayoutConstraint *)sdc_setMaximumWidth:(CGFloat)maximumWidth; 55 | - (NSLayoutConstraint *)sdc_setMaximumWidthToSuperviewWidth; 56 | - (NSLayoutConstraint *)sdc_setMaximumWidthToSuperviewWidthWithOffset:(CGFloat)offset; 57 | 58 | - (NSLayoutConstraint *)sdc_pinHeight:(CGFloat)height; 59 | - (NSLayoutConstraint *)sdc_setMinimumHeight:(CGFloat)minimumHeight; 60 | - (NSLayoutConstraint *)sdc_setMaximumHeight:(CGFloat)maximumHeight; 61 | - (NSLayoutConstraint *)sdc_setMaximumHeightToSuperviewHeight; 62 | - (NSLayoutConstraint *)sdc_setMaximumHeightToSuperviewHeightWithOffset:(CGFloat)offset; 63 | 64 | - (NSArray *)sdc_pinSize:(CGSize)size; 65 | 66 | // Pinning a view's dimensions to another view 67 | - (NSLayoutConstraint *)sdc_pinWidthToWidthOfView:(UIView *)view; 68 | - (NSLayoutConstraint *)sdc_pinWidthToWidthOfView:(UIView *)view offset:(CGFloat)offset; 69 | - (NSLayoutConstraint *)sdc_pinHeightToHeightOfView:(UIView *)view; 70 | - (NSLayoutConstraint *)sdc_pinHeightToHeightOfView:(UIView *)view offset:(CGFloat)offset; 71 | - (NSArray *)sdc_pinSizeToSizeOfView:(UIView *)view; 72 | - (NSArray *)sdc_pinSizeToSizeOfView:(UIView *)view offset:(UIOffset)offset; 73 | 74 | // Setting the spacing between a view and other view 75 | // A positive spacing (or 0) means self will be placed to the right of view 76 | // A negative spacing means self will be placed to the left of view 77 | - (NSLayoutConstraint *)sdc_pinHorizontalSpacing:(CGFloat)spacing toView:(UIView *)view; 78 | 79 | // A positive spacing (or 0) means self will be placed below view 80 | // A negative spacing means self will be placed above view 81 | - (NSLayoutConstraint *)sdc_pinVerticalSpacing:(CGFloat)spacing toView:(UIView *)view; 82 | 83 | - (NSArray *)sdc_pinSpacing:(UIOffset)spacing toView:(UIView *)view; 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertViewBackgroundView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertViewBackgroundView.m 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 11/5/13. 6 | // Initial drawRect: implementation/revision by Chris Stroud on 5/2/2014 7 | // 8 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 9 | // 10 | 11 | #import "SDCAlertViewBackgroundView.h" 12 | 13 | @implementation SDCAlertViewBackgroundView 14 | 15 | - (BOOL)isOpaque { 16 | return NO; 17 | } 18 | 19 | - (void)drawRect:(CGRect)rect { 20 | [super drawRect:rect]; 21 | 22 | CGContextRef context = UIGraphicsGetCurrentContext(); 23 | 24 | // Make sure the context is cleared 25 | CGContextClearRect(context, rect); 26 | 27 | // Set the closest matching blend mode for the context. It's really 28 | // difficult (if possible at all) to discern what Apple is using for this 29 | // but it produces a nearly identical effect, which serves our needs. 30 | CGContextSetBlendMode(context, kCGBlendModeOverlay); 31 | 32 | // Gray colorspace used for the background color 33 | CGColorSpaceRef grayColorSpace = CGColorSpaceCreateDeviceGray(); 34 | 35 | 36 | // Compensate for whatever the other layer Apple has in the hierachy (or perhaps a color-fill somewhere?) that's darkening the alert: 37 | // 38 | // [ backgroundColor]: [ (kCGColorSpaceDeviceGray)] ( 0.5 0.5 ) 39 | // 40 | // Darken the alert background prior to filling in the actual background color 41 | // 42 | // NOTE: Had to manually tweak this value to compensate for subtle brightness differences. % Grayscale is -0.6f from 43 | // Apple's apparent value. 44 | CGContextSetGrayFillColor(context, 0.44, 0.5); 45 | CGContextFillRect(context, rect); 46 | 47 | 48 | // Background color components: 49 | // 50 | // [ backgroundColor]: [ (kCGColorSpaceDeviceGray)] ( 0.97 0.96 ) 51 | // 52 | // NOTE: Had to manually tweak this value to compensate for almost-negligible transparency discrepancies. 53 | // Alpha value is now +0.1f from Apple's apparent value. 54 | CGContextSetGrayFillColor(context, 0.97f, 0.97f); 55 | CGContextFillRect(context, rect); 56 | 57 | // Gradient color components: 58 | // 59 | // [<_UIModalItemAlertBackgroundView: 0x15763a60> _gradientImageForBoundsSize:-- withInnerColor:UIDeviceWhiteColorSpace 1 0.5 outerColor:UIDeviceWhiteColorSpace 1 0] 60 | CGColorRef startColor = [[UIColor colorWithWhite:1.0f alpha:0.5f] CGColor]; 61 | CGColorRef endColor = [[UIColor colorWithWhite:1.0f alpha:0.0f] CGColor]; 62 | 63 | // Gradient colors 64 | NSArray *colors = @[(__bridge id)startColor, (__bridge id)endColor]; 65 | 66 | // Gradient locations 67 | CGFloat locations[2] = {0.0f, 1.0f}; 68 | 69 | // This gradient will default to the +[UIColor colorWithWhite:alpha:] colorspace 70 | // since UIDeviceWhiteColorSpace is seemingly private 71 | CGGradientRef gradient = CGGradientCreateWithColors(CGColorGetColorSpace(startColor), (__bridge CFArrayRef)colors, locations); 72 | 73 | /* 74 | * This trick for transforming the circular gradient is great and is largely derived from: http://stackoverflow.com/a/12665177 75 | */ 76 | 77 | // Scaling transformation and keeping track of the inverse 78 | CGAffineTransform scaleTransform = CGAffineTransformMakeScale(1.0, CGRectGetHeight(rect) / CGRectGetWidth(rect)); 79 | CGAffineTransform inverseScaleTransform = CGAffineTransformInvert(scaleTransform); 80 | 81 | // Extract the Sx and Sy elements from the inverse matrix 82 | // (See the Quartz documentation for the math behind the matrices) 83 | CGPoint inverseScale = CGPointMake(inverseScaleTransform.a, inverseScaleTransform.d); 84 | 85 | // Transform center and radius of gradient with the inverse 86 | CGPoint center = CGPointMake(CGRectGetMidX(rect) * inverseScale.x, CGRectGetMidY(rect) * inverseScale.y); 87 | CGFloat radius = CGRectGetMidX(rect) * inverseScale.x; 88 | 89 | // Draw the gradient with the scale transform on the context 90 | CGContextScaleCTM(context, scaleTransform.a, scaleTransform.d); 91 | CGContextDrawRadialGradient(context, gradient, center, 0, center, radius, kCGGradientDrawsBeforeStartLocation); 92 | // Reset the context 93 | CGContextScaleCTM(context, inverseScale.x, inverseScale.y); 94 | 95 | // Clean up the memory used by Quartz 96 | CGGradientRelease(gradient); 97 | CGColorSpaceRelease(grayColorSpace); 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /Pods/Pods-SDCAlertViewTests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2004-2013 by Mulle Kybernetik. All rights reserved. 18 | 19 | Permission to use, copy, modify and distribute this software and its documentation 20 | is hereby granted, provided that both the copyright notice and this permission 21 | notice appear in all copies of the software, derivative works or modified versions, 22 | and any portions thereof, and that both notices appear in supporting documentation, 23 | and that credit is given to Mulle Kybernetik in all documents and publicity 24 | pertaining to direct or indirect use of this code or its derivatives. 25 | 26 | THIS IS EXPERIMENTAL SOFTWARE AND IT IS KNOWN TO HAVE BUGS, SOME OF WHICH MAY HAVE 27 | SERIOUS CONSEQUENCES. THE COPYRIGHT HOLDER ALLOWS FREE USE OF THIS SOFTWARE IN ITS 28 | "AS IS" CONDITION. THE COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY 29 | DAMAGES WHATSOEVER RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE 30 | OR OF ANY DERIVATIVE WORK. 31 | 32 | Title 33 | OCMock 34 | Type 35 | PSGroupSpecifier 36 | 37 | 38 | FooterText 39 | Copyright (c) 2013 Robert Böhnke. 40 | 41 | Permission is hereby granted, free of charge, to any person obtaining a copy of 42 | this software and associated documentation files (the "Software"), to deal in 43 | the Software without restriction, including without limitation the rights to 44 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 45 | the Software, and to permit persons to whom the Software is furnished to do so, 46 | subject to the following conditions: 47 | 48 | The above copyright notice and this permission notice shall be included in all 49 | copies or substantial portions of the Software. 50 | 51 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 52 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 53 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 54 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 55 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 56 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 57 | 58 | Title 59 | RBBAnimation 60 | Type 61 | PSGroupSpecifier 62 | 63 | 64 | FooterText 65 | Copyright (c) 2013 Scott Berrevoets 66 | 67 | Permission is hereby granted, free of charge, to any person obtaining 68 | a copy of this software and associated documentation files (the 69 | "Software"), to deal in the Software without restriction, including 70 | without limitation the rights to use, copy, modify, merge, publish, 71 | distribute, sublicense, and/or sell copies of the Software, and to 72 | permit persons to whom the Software is furnished to do so, subject to 73 | the following conditions: 74 | 75 | The above copyright notice and this permission notice shall be 76 | included in all copies or substantial portions of the Software. 77 | 78 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 81 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 82 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 83 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 84 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 85 | Title 86 | SDCAutoLayout 87 | Type 88 | PSGroupSpecifier 89 | 90 | 91 | FooterText 92 | Generated by CocoaPods - http://cocoapods.org 93 | Title 94 | 95 | Type 96 | PSGroupSpecifier 97 | 98 | 99 | StringsTable 100 | Acknowledgements 101 | Title 102 | Acknowledgements 103 | 104 | 105 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/README.md: -------------------------------------------------------------------------------- 1 | # RBBAnimation 2 | 3 | `RBBAnimation` is a subclass of `CAKeyframeAnimation` that allows you to 4 | declare your __animations using blocks__ instead of writing out all the 5 | individual key-frames. 6 | 7 | This gives you greater flexibility when specifying your animations while keeping 8 | your code concise. 9 | 10 | It comes out of the box with a [replacement for 11 | CASpringAnimation](#rbbspringanimation), [support for custom easing functions 12 | such as bouncing](#rbbtweenanimation) as well as hooks to allow your writing 13 | your [own animations fully from scratch](#rbbcustomanimation). 14 | 15 | ## Installation 16 | 17 | To install RBBAnimation, I recommend the excellent [CocoaPods]. Simply add this 18 | to your Podfile 19 | 20 | ```ruby 21 | pod 'RBBAnimation', '0.3.0' 22 | ``` 23 | 24 | and you are ready to go! 25 | 26 | If you'd like to run the bundled test app, make sure to install its dependencies 27 | by running 28 | 29 | ```sh 30 | pod install 31 | ``` 32 | 33 | after cloning the repo. 34 | 35 | ## RBBCustomAnimation 36 | 37 | Use `RBBCustomAnimation` to create arbitrary animations by passing in an 38 | `RBBAnimationBlock`: 39 | 40 |

41 | Rainbow 42 |

43 | 44 | ```objc 45 | RBBCustomAnimation *rainbow = [RBBCustomAnimation animationWithKeyPath:@"backgroundColor"]; 46 | 47 | rainbow.animationBlock = ^(CGFloat elapsed, CGFloat duration) { 48 | UIColor *color = [UIColor colorWithHue:elapsed / duration 49 | saturation:1 50 | brightness:1 51 | alpha:1]; 52 | 53 | return (id)color.CGColor; 54 | }; 55 | ``` 56 | 57 | The arguments of the block are the current position of the animation as well as 58 | its total duration. 59 | 60 | Most of the time, you will probably want to use the higher-level 61 | `RBBTweenAnimation`. 62 | 63 | ## RBBSpringAnimation 64 | 65 | `RBBSpringAnimation` is a handy replacement for the private [CASpringAnimation]. 66 | Specify your spring's mass, damping, stiffness as well as its initial velocity 67 | and watch it go: 68 | 69 |

70 | Bouncing 71 |

72 | 73 | ```objc 74 | RBBSpringAnimation *spring = [RBBSpringAnimation animationWithKeyPath:@"position.y"]; 75 | 76 | spring.fromValue = @(-100.0f); 77 | spring.toValue = @(100.0f); 78 | spring.velocity = 0; 79 | spring.mass = 1; 80 | spring.damping = 10; 81 | spring.stiffness = 100; 82 | 83 | spring.additive = YES; 84 | spring.duration = [spring durationForEpsilon:0.01]; 85 | ``` 86 | 87 | ## RBBTweenAnimation 88 | 89 | `RBBTweenAnimation` allows you to animate from one value to another, similar to 90 | `CABasicAnimation` but with a greater flexibility in how the values should be 91 | interpolated. 92 | 93 | It supports the same cubic Bezier interpolation that you get from 94 | `CAMediaTimingFunction` using the `RBBCubicBezier` helper function: 95 | 96 |

97 | Ease In Out Back 98 |

99 | 100 | ```objc 101 | RBBTweenAnimation *easeInOutBack = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 102 | 103 | easeInOutBack.fromValue = @(-100.0f); 104 | easeInOutBack.toValue = @(100.0f); 105 | easeInOutBack.easing = RBBCubicBezier(0.68, -0.55, 0.265, 1.55); 106 | 107 | easeInOutBack.additive = YES; 108 | easeInOutBack.duration = 0.6; 109 | ``` 110 | 111 | However, `RBBTweenAnimation` also supports more complex easing functions such as 112 | `RBBEasingFunctionEaseOutBounce`: 113 | 114 |

115 | Bouncing 116 |

117 | 118 | ```objc 119 | RBBTweenAnimation *bounce = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 120 | bounce.fromValue = @(-100); 121 | bounce.toValue = @(100); 122 | bounce.easing = RBBEasingFunctionEaseOutBounce; 123 | 124 | bounce.additive = YES; 125 | bounce.duration = 0.8; 126 | ``` 127 | 128 | You can also specify your own easing functions, from scratch: 129 | 130 | ```objc 131 | RBBTweenAnimation *sinus = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 132 | sinus.fromValue = @(0); 133 | sinus.toValue = @(100); 134 | 135 | sinus.easing = ^CGFloat (CGFloat fraction) { 136 | return sin((fraction) * 2 * M_PI); 137 | }; 138 | 139 | sinus.additive = YES; 140 | sinus.duration = 2; 141 | ``` 142 | 143 |

144 | Sine Wave 145 |

146 | 147 | ## License 148 | 149 | RBBAnimation was built by [Robert Böhnke][robb]. It is licensed under the MIT 150 | License. 151 | 152 | If you use RBBAnimation in one of your apps, I'd love to hear about it. Feel 153 | free to follow me on Twitter where I'm [@ceterum_censeo][twitter]. 154 | 155 | [caspringanimation]: https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/QuartzCore.framework/CASpringAnimation.h 156 | [robb]: http://robb.is 157 | [twitter]: https://twitter.com/ceterum_censeo 158 | [cocoapods]: http://cocoapods.org/ 159 | -------------------------------------------------------------------------------- /Pods/RBBAnimation/RBBAnimation/RBBLinearInterpolation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBLinearInterpolation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/25/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBLinearInterpolation.h" 10 | 11 | #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR 12 | #import 13 | #define VALUE_FOR_RECT(rect) [NSValue valueWithCGRect:rect] 14 | #define RECT_VALUE(value) [value CGRectValue] 15 | #define VALUE_FOR_SIZE(size) [NSValue valueWithCGSize:size] 16 | #define SIZE_VALUE(value) [value CGSizeValue] 17 | #define VALUE_FOR_POINT(point) [NSValue valueWithCGPoint:point] 18 | #define POINT_VALUE(value) [value CGPointValue] 19 | 20 | #elif TARGET_OS_MAC 21 | 22 | #define VALUE_FOR_RECT(rect) [NSValue valueWithRect:rect] 23 | #define RECT_VALUE(value) [value rectValue] 24 | #define VALUE_FOR_SIZE(size) [NSValue valueWithSize:size] 25 | #define SIZE_VALUE(value) [value sizeValue] 26 | #define VALUE_FOR_POINT(point) [NSValue valueWithPoint:point] 27 | #define POINT_VALUE(value) [value pointValue] 28 | 29 | #endif 30 | 31 | static RBBLinearInterpolation RBBInterpolateCATransform3D(CATransform3D from, CATransform3D to) { 32 | CATransform3D delta = { 33 | .m11 = to.m11 - from.m11, 34 | .m12 = to.m12 - from.m12, 35 | .m13 = to.m13 - from.m13, 36 | .m14 = to.m14 - from.m14, 37 | .m21 = to.m21 - from.m21, 38 | .m22 = to.m22 - from.m22, 39 | .m23 = to.m23 - from.m23, 40 | .m24 = to.m24 - from.m24, 41 | .m31 = to.m31 - from.m31, 42 | .m32 = to.m32 - from.m32, 43 | .m33 = to.m33 - from.m33, 44 | .m34 = to.m34 - from.m34, 45 | .m41 = to.m41 - from.m41, 46 | .m42 = to.m42 - from.m42, 47 | .m43 = to.m43 - from.m43, 48 | .m44 = to.m44 - from.m44 49 | }; 50 | 51 | return ^(CGFloat fraction) { 52 | CATransform3D transform = { 53 | .m11 = from.m11 + fraction * delta.m11, 54 | .m12 = from.m12 + fraction * delta.m12, 55 | .m13 = from.m13 + fraction * delta.m13, 56 | .m14 = from.m14 + fraction * delta.m14, 57 | .m21 = from.m21 + fraction * delta.m21, 58 | .m22 = from.m22 + fraction * delta.m22, 59 | .m23 = from.m23 + fraction * delta.m23, 60 | .m24 = from.m24 + fraction * delta.m24, 61 | .m31 = from.m31 + fraction * delta.m31, 62 | .m32 = from.m32 + fraction * delta.m32, 63 | .m33 = from.m33 + fraction * delta.m33, 64 | .m34 = from.m34 + fraction * delta.m34, 65 | .m41 = from.m41 + fraction * delta.m41, 66 | .m42 = from.m42 + fraction * delta.m42, 67 | .m43 = from.m43 + fraction * delta.m43, 68 | .m44 = from.m44 + fraction * delta.m44 69 | }; 70 | 71 | return [NSValue valueWithCATransform3D:transform]; 72 | }; 73 | } 74 | 75 | static RBBLinearInterpolation RBBInterpolateCGRect(CGRect from, CGRect to) { 76 | CGFloat deltaX = to.origin.x - from.origin.x; 77 | CGFloat deltaY = to.origin.y - from.origin.y; 78 | CGFloat deltaWidth = to.size.width - from.size.width; 79 | CGFloat deltaHeight = to.size.height - from.size.height; 80 | 81 | return ^(CGFloat fraction) { 82 | CGRect rect = { 83 | .origin.x = from.origin.x + fraction * deltaX, 84 | .origin.y = from.origin.y + fraction * deltaY, 85 | .size.width = from.size.width + fraction * deltaWidth, 86 | .size.height = from.size.height + fraction * deltaHeight 87 | }; 88 | 89 | return VALUE_FOR_RECT(rect); 90 | }; 91 | } 92 | 93 | static RBBLinearInterpolation RBBInterpolateCGPoint(CGPoint from, CGPoint to) { 94 | CGFloat deltaX = to.x - from.x; 95 | CGFloat deltaY = to.y - from.y; 96 | 97 | return ^(CGFloat fraction) { 98 | CGPoint point = { 99 | .x = from.x + fraction * deltaX, 100 | .y = from.y + fraction * deltaY, 101 | }; 102 | 103 | return VALUE_FOR_POINT(point); 104 | }; 105 | } 106 | 107 | static RBBLinearInterpolation RBBInterpolateCGSize(CGSize from, CGSize to) { 108 | CGFloat deltaWidth = to.width - from.width; 109 | CGFloat deltaHeight = to.height - from.height; 110 | 111 | return ^(CGFloat fraction) { 112 | CGSize size = { 113 | .width = from.width + fraction * deltaWidth, 114 | .height = from.height + fraction * deltaHeight, 115 | }; 116 | 117 | return VALUE_FOR_SIZE(size); 118 | }; 119 | } 120 | 121 | static RBBLinearInterpolation RBBInterpolateCGFloat(CGFloat from, CGFloat to) { 122 | CGFloat delta = to - from; 123 | 124 | return ^(CGFloat fraction) { 125 | return @(from + fraction * delta); 126 | }; 127 | }; 128 | 129 | extern RBBLinearInterpolation RBBInterpolate(NSValue *from, NSValue *to) { 130 | NSCParameterAssert(([from isKindOfClass:NSNumber.class] && [to isKindOfClass:NSNumber.class]) || strcmp(from.objCType, to.objCType) == 0); 131 | 132 | if (strcmp(from.objCType, @encode(CATransform3D)) == 0) { 133 | return RBBInterpolateCATransform3D(from.CATransform3DValue, to.CATransform3DValue); 134 | } 135 | 136 | if (strcmp(from.objCType, @encode(CGRect)) == 0) { 137 | return RBBInterpolateCGRect(RECT_VALUE(from), RECT_VALUE(to)); 138 | } 139 | 140 | if (strcmp(from.objCType, @encode(CGPoint)) == 0) { 141 | return RBBInterpolateCGPoint(POINT_VALUE(from), POINT_VALUE(to)); 142 | } 143 | 144 | if (strcmp(from.objCType, @encode(CGSize)) == 0) { 145 | return RBBInterpolateCGSize(SIZE_VALUE(from), SIZE_VALUE(to)); 146 | } 147 | 148 | if ([from isKindOfClass:NSNumber.class]) { 149 | #if CGFLOAT_IS_DOUBLE 150 | return RBBInterpolateCGFloat([(NSNumber *)from doubleValue], [(NSNumber *)to doubleValue]); 151 | #else 152 | return RBBInterpolateCGFloat([(NSNumber *)from floatValue], [(NSNumber *)to doubleValue]); 153 | #endif 154 | } 155 | 156 | return ^(CGFloat fraction) { 157 | return fraction < 0.5 ? from : to; 158 | }; 159 | } 160 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertViewCoordinator.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertViewCoordinator.m 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 1/25/14. 6 | // Copyright (c) 2014 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import "SDCAlertViewCoordinator.h" 10 | 11 | #import "SDCAlertView.h" 12 | #import "SDCAlertViewController.h" 13 | 14 | @interface SDCAlertViewCoordinator () 15 | @property (nonatomic, strong) UIWindow *userWindow; 16 | @property (nonatomic, strong) UIWindow *alertWindow; 17 | @property (nonatomic, strong) NSMutableArray *alerts; 18 | @property (nonatomic, weak) SDCAlertView *presentingAlert; 19 | @property (nonatomic, weak) SDCAlertView *dismissingAlert; 20 | @property (nonatomic, weak) SDCAlertView *visibleAlert; 21 | @property (nonatomic, strong) NSMutableArray *transitionQueue; 22 | @end 23 | 24 | @implementation SDCAlertViewCoordinator 25 | 26 | - (UIWindow *)alertWindow { 27 | if (!_alertWindow) { 28 | _alertWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 29 | _alertWindow.backgroundColor = [UIColor clearColor]; 30 | _alertWindow.rootViewController = [[SDCAlertViewController alloc] init]; 31 | _alertWindow.windowLevel = UIWindowLevelAlert; 32 | } 33 | 34 | return _alertWindow; 35 | } 36 | 37 | - (NSMutableArray *)alerts { 38 | if (!_alerts) 39 | _alerts = [NSMutableArray array]; 40 | return _alerts; 41 | } 42 | 43 | - (id)init { 44 | self = [super init]; 45 | 46 | if (self) { 47 | _userWindow = [[UIApplication sharedApplication] keyWindow]; 48 | _transitionQueue = [NSMutableArray array]; 49 | } 50 | 51 | return self; 52 | } 53 | 54 | + (instancetype)sharedCoordinator { 55 | static SDCAlertViewCoordinator *sharedCoordinator; 56 | static dispatch_once_t onceToken; 57 | dispatch_once(&onceToken, ^{ 58 | sharedCoordinator = [[self alloc] init]; 59 | }); 60 | 61 | return sharedCoordinator; 62 | } 63 | 64 | #pragma mark - Transition Queue 65 | 66 | - (BOOL)enqueuePresentingAnimationOfAlert:(SDCAlertView *)alert { 67 | if (!self.presentingAlert && !self.dismissingAlert) 68 | return NO; 69 | 70 | NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:@selector(presentAlert:)]; 71 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; 72 | [invocation setSelector:@selector(presentAlert:)]; 73 | [invocation setArgument:&alert atIndex:2]; 74 | [invocation retainArguments]; 75 | 76 | [self.transitionQueue addObject:invocation]; 77 | 78 | return YES; 79 | } 80 | 81 | - (BOOL)enqueueDismissingAnimationOfAlert:(SDCAlertView *)alert withButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { 82 | if (!self.presentingAlert && !self.dismissingAlert) 83 | return NO; 84 | 85 | NSMethodSignature *methodSignature = [[self class] instanceMethodSignatureForSelector:@selector(dismissAlert:withButtonIndex:animated:)]; 86 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; 87 | [invocation setSelector:@selector(dismissAlert:withButtonIndex:animated:)]; 88 | [invocation setArgument:&alert atIndex:2]; 89 | [invocation setArgument:&buttonIndex atIndex:3]; 90 | [invocation setArgument:&animated atIndex:4]; 91 | [invocation retainArguments]; 92 | 93 | [self.transitionQueue addObject:invocation]; 94 | 95 | return YES; 96 | } 97 | 98 | - (void)dequeueNextTransition { 99 | NSInvocation *nextInvocation = [self.transitionQueue firstObject]; 100 | [self.transitionQueue removeObject:nextInvocation]; 101 | 102 | [nextInvocation invokeWithTarget:self]; 103 | } 104 | 105 | #pragma mark - Presenting & Dismissing 106 | 107 | - (void)beginTransitioningFromAlert:(SDCAlertView *)oldAlert toAlert:(SDCAlertView *)newAlert { 108 | self.visibleAlert = nil; 109 | self.presentingAlert = newAlert; 110 | self.dismissingAlert = oldAlert; 111 | } 112 | 113 | - (void)endTransitioning { 114 | self.visibleAlert = self.presentingAlert; 115 | self.presentingAlert = nil; 116 | self.dismissingAlert = nil; 117 | } 118 | 119 | - (void)showAlert:(SDCAlertView *)newAlert 120 | replacingAlert:(SDCAlertView *)oldAlert 121 | animated:(BOOL)animated 122 | completion:(void(^)())completionHandler { 123 | if (!newAlert) 124 | [self resaturateUI]; 125 | 126 | [self beginTransitioningFromAlert:oldAlert toAlert:newAlert]; 127 | 128 | SDCAlertViewController *controller = (SDCAlertViewController *)self.alertWindow.rootViewController; 129 | [controller replaceAlert:oldAlert withAlert:newAlert animated:animated completion:^{ 130 | [self endTransitioning]; 131 | 132 | if (!newAlert) 133 | [self returnToUserWindow]; 134 | 135 | if (completionHandler) 136 | completionHandler(); 137 | 138 | [self dequeueNextTransition]; 139 | }]; 140 | } 141 | 142 | - (void)presentAlert:(SDCAlertView *)alert { 143 | if ([self enqueuePresentingAnimationOfAlert:alert]) 144 | return; 145 | 146 | [self.alerts addObject:alert]; 147 | 148 | if (!self.visibleAlert) 149 | [self makeAlertWindowKeyWindow]; 150 | 151 | [alert willBePresented]; 152 | [self showAlert:alert replacingAlert:self.visibleAlert animated:YES completion:^{ 153 | [alert wasPresented]; 154 | }]; 155 | } 156 | 157 | - (void)dismissAlert:(SDCAlertView *)alert withButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { 158 | if ([self dismissAlertImmediately:alert withButtonIndex:buttonIndex] || 159 | [self enqueueDismissingAnimationOfAlert:alert withButtonIndex:buttonIndex animated:animated]) 160 | return; 161 | 162 | [self.alerts removeObject:alert]; 163 | 164 | [alert willBeDismissedWithButtonIndex:buttonIndex]; 165 | SDCAlertView *nextAlert = [self.alerts lastObject]; 166 | 167 | [self showAlert:nextAlert replacingAlert:alert animated:animated completion:^{ 168 | [alert wasDismissedWithButtonIndex:buttonIndex]; 169 | [nextAlert wasPresented]; 170 | }]; 171 | } 172 | 173 | - (BOOL)dismissAlertImmediately:(SDCAlertView *)alert withButtonIndex:(NSInteger)buttonIndex { 174 | if (self.visibleAlert == alert || self.presentingAlert == alert) 175 | return NO; 176 | 177 | [self.alerts removeObject:alert]; 178 | [alert willBeDismissedWithButtonIndex:buttonIndex]; 179 | [alert wasDismissedWithButtonIndex:buttonIndex]; 180 | 181 | return YES; 182 | } 183 | 184 | #pragma mark - Window Switching 185 | 186 | - (void)resaturateUI { 187 | self.userWindow.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic; 188 | } 189 | 190 | - (void)makeAlertWindowKeyWindow { 191 | self.userWindow.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed; 192 | [self.alertWindow makeKeyAndVisible]; 193 | } 194 | 195 | - (void)returnToUserWindow { 196 | [self.userWindow makeKeyAndVisible]; 197 | 198 | // Set the alert window to nil so that it gets removed from the screen. Otherwise, since its windowLevel is set to 199 | // UIWindowLevelAlert, it will cover up the current window, causing it to appear unresponsive. 200 | self.alertWindow = nil; 201 | } 202 | 203 | @end 204 | -------------------------------------------------------------------------------- /SDCAlertView/SDCViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDCViewController.m 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 9/20/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | @import MapKit; 10 | 11 | #import "SDCViewController.h" 12 | 13 | #import "SDCAlertView.h" 14 | #import "UIView+SDCAutoLayout.h" 15 | 16 | @interface SDCViewController () 17 | 18 | @end 19 | 20 | @implementation SDCViewController 21 | 22 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 23 | if (indexPath.section == 0) { 24 | UIAlertView *a = [[UIAlertView alloc] initWithTitle:@"Title" 25 | message:@"This is a message" 26 | delegate:self 27 | cancelButtonTitle:@"Cancel" 28 | otherButtonTitles:@"Button 1", @"Button 2", nil]; 29 | [a show]; 30 | 31 | } else if (indexPath.section == 1) { 32 | if (indexPath.row == 0) { 33 | SDCAlertView *a = [[SDCAlertView alloc] initWithTitle:@"Title" 34 | message:@"This is a message" 35 | delegate:self 36 | cancelButtonTitle:@"Cancel" 37 | otherButtonTitles:@"OK", nil]; 38 | [a show]; 39 | } else if (indexPath.row == 1) { 40 | [[[SDCAlertView alloc] initWithTitle:@"Title" 41 | message:@"This is a message" 42 | delegate:nil 43 | cancelButtonTitle:@"Cancel" 44 | otherButtonTitles:@"OK", @"Whatever", nil] show]; 45 | } else if (indexPath.row == 2) { 46 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:@"Title" 47 | message:@"This is a message" 48 | delegate:nil 49 | cancelButtonTitle:nil 50 | otherButtonTitles:@"OK", nil]; 51 | alert.alertViewStyle = SDCAlertViewStylePlainTextInput; 52 | 53 | [alert show]; 54 | } else if (indexPath.row == 3) { 55 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:@"Title" 56 | message:@"This is a message" 57 | delegate:nil 58 | cancelButtonTitle:nil 59 | otherButtonTitles:@"OK", nil]; 60 | alert.alertViewStyle = SDCAlertViewStyleLoginAndPasswordInput; 61 | 62 | [alert show]; 63 | } 64 | } else if (indexPath.section == 2) { 65 | if (indexPath.row == 0) { 66 | 67 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:@"Please wait..." 68 | message:@"Please wait until we're done doing what we're doing" 69 | delegate:nil 70 | cancelButtonTitle:nil 71 | otherButtonTitles:@"OK", nil]; 72 | 73 | UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar]; 74 | progressView.progress = 0; 75 | 76 | [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(updateProgressView:) userInfo:progressView repeats:YES]; 77 | 78 | [progressView setTranslatesAutoresizingMaskIntoConstraints:NO]; 79 | [alert.contentView addSubview:progressView]; 80 | 81 | [progressView sdc_pinWidthToWidthOfView:alert.contentView offset:-20]; 82 | [progressView sdc_horizontallyCenterInSuperview]; 83 | 84 | [alert.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[progressView]|" 85 | options:0 86 | metrics:nil 87 | views:NSDictionaryOfVariableBindings(progressView)]]; 88 | 89 | [alert show]; 90 | } else if (indexPath.row == 1) { 91 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:@"Contacting Server" 92 | message:@"We're doing some network stuff. Hang on..." 93 | delegate:nil 94 | cancelButtonTitle:@"OK" 95 | otherButtonTitles:nil]; 96 | 97 | UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 98 | [spinner setTranslatesAutoresizingMaskIntoConstraints:NO]; 99 | [spinner startAnimating]; 100 | [alert.contentView addSubview:spinner]; 101 | 102 | [spinner sdc_centerInSuperview]; 103 | 104 | [alert show]; 105 | } else if (indexPath.row == 2) { 106 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:@"Cupertino, CA" 107 | message:nil 108 | delegate:nil 109 | cancelButtonTitle:@"OK" 110 | otherButtonTitles:nil]; 111 | MKMapView *mapView = [[MKMapView alloc] init]; 112 | [mapView setTranslatesAutoresizingMaskIntoConstraints:NO]; 113 | 114 | MKCoordinateRegion region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(37.3175, -122.041944), MKCoordinateSpanMake(.1, .1)); 115 | [mapView setRegion:region animated:YES]; 116 | [alert.contentView addSubview:mapView]; 117 | 118 | [mapView sdc_pinWidthToWidthOfView:alert.contentView]; 119 | [mapView sdc_centerInSuperview]; 120 | [mapView sdc_pinHeight:120]; 121 | 122 | [alert show]; 123 | } 124 | } 125 | 126 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 127 | } 128 | 129 | - (void)updateProgressView:(NSTimer *)timer { 130 | UIProgressView *progressView = [timer userInfo]; 131 | 132 | if (progressView.progress < 1) 133 | progressView.progress += .05; 134 | else 135 | [timer invalidate]; 136 | } 137 | 138 | - (IBAction)changeAppearance:(UISegmentedControl *)sender { 139 | if (sender.selectedSegmentIndex == 0) { 140 | [[SDCAlertView appearance] setTitleLabelFont:[UIFont boldSystemFontOfSize:17]]; 141 | [[SDCAlertView appearance] setMessageLabelFont:[UIFont systemFontOfSize:14]]; 142 | [[SDCAlertView appearance] setTextFieldFont:[UIFont systemFontOfSize:13]]; 143 | [[SDCAlertView appearance] setSuggestedButtonFont:[UIFont boldSystemFontOfSize:17]]; 144 | [[SDCAlertView appearance] setNormalButtonFont:[UIFont systemFontOfSize:17]]; 145 | [[SDCAlertView appearance] setButtonTextColor:[UIColor colorWithRed:0/255.0 green:122/255.0 blue:255/255.0 alpha:1]]; 146 | [[SDCAlertView appearance] setTextFieldTextColor:[UIColor blackColor]]; 147 | [[SDCAlertView appearance] setTitleLabelTextColor:[UIColor blackColor]]; 148 | [[SDCAlertView appearance] setMessageLabelTextColor:[UIColor blackColor]]; 149 | } 150 | else { 151 | [[SDCAlertView appearance] setTitleLabelFont:[UIFont boldSystemFontOfSize:22]]; 152 | [[SDCAlertView appearance] setMessageLabelFont:[UIFont italicSystemFontOfSize:14]]; 153 | [[SDCAlertView appearance] setNormalButtonFont:[UIFont boldSystemFontOfSize:12]]; 154 | [[SDCAlertView appearance] setSuggestedButtonFont:[UIFont italicSystemFontOfSize:12]]; 155 | [[SDCAlertView appearance] setTextFieldFont:[UIFont italicSystemFontOfSize:12]]; 156 | [[SDCAlertView appearance] setButtonTextColor:[UIColor grayColor]]; 157 | [[SDCAlertView appearance] setTextFieldTextColor:[UIColor purpleColor]]; 158 | [[SDCAlertView appearance] setTitleLabelTextColor:[UIColor greenColor]]; 159 | [[SDCAlertView appearance] setMessageLabelTextColor:[UIColor yellowColor]]; 160 | 161 | } 162 | } 163 | 164 | @end 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #SDCAlertView 2 | 3 | `SDCAlertView` doesn't just look like a system alert in terms of user interface elements, it is the result of completely reverse-engineering `UIAlertView`. View hierarchy, labels, buttons, animations, user interaction; everything has been looked at and incorporated as much as possible. 4 | 5 | You can think of `SDCAlertView` as `UIAlertView` on steroids. It has added functionality such as a `contentView` property and block syntax, while still keeping the `UIAlertView` look. 6 | 7 | ![Animated GIF showing alert](http://sberrevoets.github.io/SDCAlertView/ProgressViewAlert.gif) 8 | 9 | ## Installation 10 | The easiest way to install is, of course, by using CocoaPods. The name of the pod is `SDCAlertView`. 11 | 12 | If you're not using CocoaPods, you need: 13 | 14 | - SDCAlertView.{h,m} 15 | - SDCAlertViewTransitioning.h 16 | - SDCAlertViewCoordinator.{h,m} 17 | - SDCAlertViewController.{h,m} 18 | - SDCAlertViewContentView.{h,m} 19 | - SDCAlertViewBackgroundView.{h,m} 20 | - SDCIntrinsicallySizedView.{h,m} 21 | 22 | The project also depends on [RBBAnimation](https://github.com/robb/RBBAnimation) and [SDCAutoLayout](https://github.com/Scott90/SDCAutoLayout). These dependencies are automatically handled for you if you use CocoaPods. 23 | 24 | ## Usage 25 | `SDCAlertView` is for use in iOS 7 only. It will not work properly on iOS 6.1 or below. Using `SDCAlertView` is very simple: just import SDCAlertView.h and use it as you would `UIAlertView`. 26 | 27 | ### Basic 28 | 29 | Showing a basic `SDCAlertView` alert looks just like showing a basic `UIAlertView` alert: 30 | ```objc 31 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:@"Title" 32 | message:@"This is a message" 33 | delegate:self 34 | cancelButtonTitle:@"Cancel" 35 | otherButtonTitles:@"OK", nil]; 36 | [alert show]; 37 | ``` 38 | 39 | Or you can use one of the convenience methods: 40 | ```objc 41 | [SDCAlertView alertWithTitle:@"Title" message:@"This is a message" buttons:@[@"OK"]]; 42 | ``` 43 | 44 | ### Block syntax 45 | 46 | Block syntax saves you from having to use a delegate: 47 | ```objc 48 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:@"Title" 49 | message:@"This is a message" 50 | delegate:nil 51 | cancelButtonTitle:@"Cancel" 52 | otherButtonTitles:@"OK", nil]; 53 | [alert showWithDismissHandler:^(NSInteger buttonIndex) { 54 | NSLog(@"Tapped button: %@", @(buttonIndex)); 55 | }]; 56 | ``` 57 | 58 | ### `contentView` 59 | 60 | Of course, you're not using `SDCAlertView`'s full potential unless you are using the `contentView`: 61 | ```objc 62 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:@"Title" 63 | message:@"This is a message" 64 | delegate:self 65 | cancelButtonTitle:@"Cancel" 66 | otherButtonTitles:@"OK", nil]; 67 | 68 | UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] init]; 69 | spinner.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; 70 | [spinner setTranslatesAutoresizingMaskIntoConstraints:NO]; 71 | [spinner startAnimating]; 72 | 73 | [alert.contentView addSubview:spinner]; 74 | [spinner sdc_horizontallyCenterInSuperview]; 75 | [spinner sdc_verticallyCenterInSuperviewWithOffset:SDCAutoLayoutStandardSiblingDistance]; 76 | [alert show]; 77 | ``` 78 | 79 | ### Additional delegate methods 80 | 81 | You can also use the `alertView:shouldDismissWithButtonIndex:` and `alertView:shouldDeselectButtonAtIndex:` to prevent an alert from dismissing: 82 | ```objc 83 | - (void)showAlert { 84 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:title 85 | message:message 86 | delegate:self 87 | cancelButtonTitle:@"Cancel" 88 | otherButtonTitles:nil]; 89 | [alert show]; 90 | } 91 | 92 | - (BOOL)alertView:(SDCAlertView *)alertView shouldDismissWithButtonIndex:(NSInteger)buttonIndex { 93 | return NO; 94 | } 95 | 96 | - (BOOL)alertView:(SDCAlertView *)alertView shouldDeselectButtonAtIndex:(NSInteger)buttonIndex { 97 | return YES; 98 | } 99 | ``` 100 | This will deselect the cancel button when it's tapped, but it won't actually dismiss the alert. Useful for password-like alerts that you don't want dismissed until the right password is entered. 101 | 102 | ### Styling and appearance 103 | 104 | `SDCAlertView` uses the `tintColor` for buttons and any subviews you add to the `contentView`. If you are looking for more customizations, you can use `UIAppearance` to style alerts (per instance or all at once): 105 | ```objc 106 | [[SDCAlertView appearance] setTitleLabelFont:[UIFont boldSystemFontOfSize:22]]; 107 | [[SDCAlertView appearance] setMessageLabelFont:[UIFont italicSystemFontOfSize:14]]; 108 | [[SDCAlertView appearance] setNormalButtonFont:[UIFont boldSystemFontOfSize:12]]; 109 | [[SDCAlertView appearance] setSuggestedButtonFont:[UIFont italicSystemFontOfSize:12]]; 110 | [[SDCAlertView appearance] setTextFieldFont:[UIFont italicSystemFontOfSize:12]]; 111 | [[SDCAlertView appearance] setButtonTextColor:[UIColor grayColor]]; // will always override the tintColor 112 | [[SDCAlertView appearance] setTextFieldTextColor:[UIColor purpleColor]]; 113 | [[SDCAlertView appearance] setTitleLabelTextColor:[UIColor greenColor]]; 114 | [[SDCAlertView appearance] setMessageLabelTextColor:[UIColor yellowColor]]; 115 | ``` 116 | 117 | If you're feeling particularly adventurous, `SDCAlertView` makes it very easy to customize the way alerts are presented and dismissed. Set the `transitionCoordinator` property to a custom class that conforms to `SDCAlertViewTransitioning`, and implement the three protocol methods. For more detailed instructions, see SDCAlertViewTransitioning.h. 118 | 119 | ## Behavior different from `UIAlertView` 120 | Unfortunately, there are a few things that can't or won't be duplicated: 121 | 122 | - Special interaction with the system. The system does not consider instances of `SDCAlertView` actual alerts, which means that, for example, the `alertViewCancel:` method from `SDCAlertViewDelegate` will never be called. 123 | - `UITextField` placeholders in different languages. "Login" and "Password" are entered as localized strings, but they aren't actually translated. 124 | - Some behavior is purposely not ported from `UIAlertView`. These cases are discussed in SDCAlertView.h. 125 | 126 | ## New in 1.4 127 | 128 | **What's New:** 129 | - Added the ability to position a two-button alert vertically as opposed to horizontally 130 | - Added `attributedTitle` and `attributedMessage` properties 131 | 132 | **Bug Fixes:** 133 | - Auto-layout doesn't complain anymore when using `[[SDCAlertView alloc] init]` 134 | - Fixes a bug that would not show correct button titles in certain alert configurations 135 | - Instead of clipping button text, it now reduces the size of text on buttons appropriately 136 | 137 | ## Support 138 | I'm pretty active on [Stack Overflow](http://stackoverflow.com/users/751268/scott-berrevoets), so please use that if you have any questions. You can also use [Twitter](http://twitter.com/ScottBerrevoets) to contact me directly. 139 | 140 | If you are experiencing bugs, feel free to post an issue or submit a pull request. I don't bite, promise! 141 | 142 | ## Credits 143 | Some credits are in order: 144 | 145 | - Robert Böhnke ([@robb](https://github.com/robb)): [RBBAnimation](https://github.com/robb/RBBAnimation) 146 | - Lee McDermott ([@lmcd](https://github.com/lmcd)) for reverse-engineering the showing and dismissing animations. 147 | - César Castillo ([@JagCesar](https://github.com/JagCesar)) for the great idea of using a `UIToolbar` for easy live blurring (used in earlier versions of SDCAlertView). 148 | 149 | And everyone else who contributed by reporting issues, creating pull requests, or in some other way! -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertView.h 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 9/20/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | FOUNDATION_EXPORT CGFloat const SDCAlertViewWidth; 12 | 13 | typedef NS_ENUM(NSInteger, SDCAlertViewStyle) { 14 | SDCAlertViewStyleDefault = 0, 15 | SDCAlertViewStyleSecureTextInput, 16 | SDCAlertViewStylePlainTextInput, 17 | SDCAlertViewStyleLoginAndPasswordInput 18 | }; 19 | 20 | @class SDCAlertView; 21 | 22 | @protocol SDCAlertViewDelegate 23 | @optional 24 | 25 | - (void)alertView:(SDCAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; 26 | 27 | /** 28 | * To make SDCAlertViewDelegate match all methods from UIAlertView, alertViewCancel: is added to this protocol. However, 29 | * since SDCAlertView is not a system alert and this method will only be called if the system dismisses the alert, the 30 | * delegate will never receive the alertViewCancel: message. 31 | */ 32 | - (void)alertViewCancel:(SDCAlertView *)alertView DEPRECATED_MSG_ATTRIBUTE("This method will never be called. See SDCAlertView.h for more information."); 33 | 34 | - (void)willPresentAlertView:(SDCAlertView *)alertView; 35 | - (void)didPresentAlertView:(SDCAlertView *)alertView; 36 | 37 | - (BOOL)alertView:(SDCAlertView *)alertView shouldDismissWithButtonIndex:(NSInteger)buttonIndex; 38 | - (void)alertView:(SDCAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex; 39 | - (void)alertView:(SDCAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex; 40 | 41 | /** 42 | * This method is sent when the user presses a button, but the alert is prevented from being dismissed using either 43 | * the \c alertView:shouldDismissWithButtonIndex: delegate method, or the \c shouldDismissHandler property. The return 44 | * value of this method (or its corresponding block property \c shouldDeselectButtonHandler) determines whether 45 | * the button stays selected after it has been tapped. The default value, which is returned if neither the delegate method 46 | * is implemented or the block property set, is YES. 47 | */ 48 | - (BOOL)alertView:(SDCAlertView *)alertView shouldDeselectButtonAtIndex:(NSInteger)buttonIndex; 49 | 50 | - (BOOL)alertViewShouldEnableFirstOtherButton:(SDCAlertView *)alertView; 51 | 52 | @end 53 | 54 | @interface SDCAlertView : UIView 55 | 56 | @property (nonatomic, copy) NSString *title; 57 | @property (nonatomic, copy) NSString *message; 58 | 59 | @property (nonatomic) NSInteger cancelButtonIndex; 60 | @property (nonatomic, readonly) NSInteger firstOtherButtonIndex; 61 | @property (nonatomic, readonly) NSInteger numberOfButtons; 62 | 63 | @property (nonatomic, readonly, getter = isVisible) BOOL visible; 64 | 65 | @property (nonatomic) SDCAlertViewStyle alertViewStyle; 66 | 67 | /** 68 | * The contentView property can be used to display any arbitrary view in an alert view by adding these views to the contentView. 69 | * SDCAlertView uses auto-layout to layout all its subviews, including the contentView. That means that you should not 70 | * modify the contentView's frame property, as it will do nothing. Use NSLayoutConstraint or helper methods included in 71 | * SDCAutoLayout to modify the contentView's dimensions. 72 | * 73 | * The contentView will take up the entire width of the alert. The height cannot be automatically determined and will 74 | * need to be explicitly defined. 75 | * 76 | * If there are no subviews, the contentView will not be added to the alert. 77 | */ 78 | @property (nonatomic, readonly) UIView *contentView; 79 | 80 | @property (nonatomic, weak) id delegate; 81 | 82 | /* 83 | * The following properties are blocks as alternatives to using delegate methods. It's possible to implement both the 84 | * delegate and set its corresponding block. In that case, the delegate will be called before the block will be executed. 85 | * 86 | * In the case of alertView:shouldDismissWithButtonIndex:/shouldDismissHandler and 87 | * alertView:shouldDeselectButtonAtIndex:/shouldDeselectButtonHandler, the delegate will always have precedence. That 88 | * meansthat if the delegate is set, the block will NOT be executed. 89 | */ 90 | 91 | /// Alternative property for \c alertView:clickedButtonAtIndex: 92 | @property (nonatomic, copy) void (^clickedButtonHandler)(NSInteger buttonIndex); 93 | 94 | /// Alternative property for \c alertView:shouldDismissWithButtonIndex: 95 | @property (nonatomic, copy) BOOL (^shouldDismissHandler)(NSInteger buttonIndex); 96 | 97 | /// Alternative property for \c alertView:willDismissWithButtonIndex: 98 | @property (nonatomic, copy) void (^willDismissHandler)(NSInteger buttonIndex); 99 | 100 | /// Alternative property for \c alertView:didDismissWithButtonIndex: 101 | @property (nonatomic, copy) void (^didDismissHandler)(NSInteger buttonIndex); 102 | 103 | /// Alternative property for \c alertView:shouldDeselectButtonAtIndex: 104 | @property (nonatomic, copy) BOOL (^shouldDeselectButtonHandler)(NSInteger buttonIndex); 105 | 106 | - (instancetype)initWithTitle:(NSString *)title 107 | message:(NSString *)message 108 | delegate:(id)delegate 109 | cancelButtonTitle:(NSString *)cancelButtonTitle 110 | otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; 111 | 112 | /* 113 | * Showing and dismissing an alert works largely the same as it does with UIAlertView. Animations will not be interrupted, 114 | * so showing an alert while another alert is already animating will finish the first alert, then show the second. The 115 | * behavior is a little bit different in edge cases, like when doing this: 116 | * 117 | * SDCAlertView *alert1 = ...; 118 | * SDCAlertView *alert2 = ...; 119 | * 120 | * [alert1 show]; 121 | * [alert1 dismissWithClickedButtonIndex:0]; 122 | * [alert2 show]; 123 | * 124 | * Take a look at https://github.com/Scott90/SDCAlertView/issues/25 for a discussion of the exact behavior. 125 | */ 126 | 127 | - (void)show; 128 | 129 | - (NSInteger)addButtonWithTitle:(NSString *)title; 130 | - (NSString *)buttonTitleAtIndex:(NSInteger)index; 131 | 132 | - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated; 133 | 134 | - (UITextField *)textFieldAtIndex:(NSInteger)textFieldIndex; 135 | 136 | @end 137 | 138 | @interface SDCAlertView (SDCAlertViewSpecific) 139 | 140 | /** 141 | * Set this property to \c YES to show the buttons of a two-button alert stacked on top of each other, as opposed to 142 | * horizontally next to each other. Defaults to \c NO. 143 | */ 144 | @property (nonatomic) BOOL alwaysShowsButtonsVertically; 145 | @end 146 | 147 | @interface SDCAlertView (SDCAlertViewAttributedStrings) 148 | 149 | /* 150 | * If a string has a title with attributes, the equivalent UIAppearance properties for that attribute will not work 151 | * anymore. For example, the following code will result in a red title: 152 | * 153 | * NSDictionary *attributes = @{NSForegroundColorAttributeName: [UIColor redColor]}; 154 | * alert.attributedTitle = [[NSAttributedString alloc] initWithTitle:@"Title" attributes:attributes]; 155 | * alert.titleLabelTextColor = [UIColor greenColor]; 156 | * 157 | * This is an unfortunate side effect of UIAppearance, so it's recommended to use either attributed strings or their 158 | * equivalent UIAppearance properties, not both. 159 | */ 160 | 161 | 162 | /** 163 | * The attributed title for the alert. Both \c title and \c attributedTitle can be used to set the title of the alert, 164 | * the title will be set to whichever was called last. That means that setting \c title to \c nil after setting the 165 | * \c attributedTitle will result in no title showing. 166 | */ 167 | @property (nonatomic, copy) NSAttributedString *attributedTitle; 168 | 169 | /** 170 | * The attributed message for the alert. Both \c message and \c attributedMessage can be used to set the message of the 171 | * alert, but the message will be set to whichever was called last. That means that setting \c mesage to \c nil after 172 | * setting the \c attributedMessage will result in no message showing. 173 | */ 174 | @property (nonatomic, copy) NSAttributedString *attributedMessage; 175 | 176 | @end 177 | 178 | @interface SDCAlertView (Convenience) 179 | 180 | /** 181 | * Set a dismiss handler and show the alert. 182 | */ 183 | - (void)showWithDismissHandler:(void(^)(NSInteger buttonIndex))dismissHandler; 184 | 185 | /* 186 | * The methods below are convenience methods to easily make an alert appear. All methods create an alert, show it with 187 | * the provided arguments, and return the alert that was shown. The delegate isn't set, but can be changed using the 188 | * delegate property. 189 | * 190 | * Methods with a non-nil and non-empty buttons array will add the buttons in order, making the first button of the array 191 | * the cancel button. Method calls with a non-nil subview argument will have the subview added to the alert's contentView. 192 | */ 193 | 194 | + (instancetype)alertWithTitle:(NSString *)title message:(NSString *)message; 195 | + (instancetype)alertWithTitle:(NSString *)title message:(NSString *)message buttons:(NSArray *)buttons; 196 | 197 | + (instancetype)alertWithSubview:(UIView *)subview; 198 | + (instancetype)alertWithTitle:(NSString *)title subview:(UIView *)subview; 199 | + (instancetype)alertWithTitle:(NSString *)title message:(NSString *)message subview:(UIView *)subview; 200 | + (instancetype)alertWithTitle:(NSString *)title message:(NSString *)message subview:(UIView *)subview buttons:(NSArray *)buttons; 201 | 202 | @end 203 | 204 | @interface SDCAlertView (UIAppearance) 205 | 206 | @property (nonatomic, strong) UIFont *titleLabelFont UI_APPEARANCE_SELECTOR; 207 | @property (nonatomic, strong) UIColor *titleLabelTextColor UI_APPEARANCE_SELECTOR; 208 | @property (nonatomic, strong) UIFont *messageLabelFont UI_APPEARANCE_SELECTOR; 209 | @property (nonatomic, strong) UIColor *messageLabelTextColor UI_APPEARANCE_SELECTOR; 210 | @property (nonatomic, strong) UIFont *textFieldFont UI_APPEARANCE_SELECTOR; 211 | @property (nonatomic, strong) UIColor *textFieldTextColor UI_APPEARANCE_SELECTOR; 212 | @property (nonatomic, strong) UIFont *suggestedButtonFont UI_APPEARANCE_SELECTOR; 213 | @property (nonatomic, strong) UIFont *normalButtonFont UI_APPEARANCE_SELECTOR; 214 | @property (nonatomic, strong) UIColor *buttonTextColor UI_APPEARANCE_SELECTOR; // Will override tintColor 215 | 216 | @end 217 | 218 | @interface UIColor (SDCAlertViewColors) 219 | + (UIColor *)sdc_alertSeparatorColor; 220 | + (UIColor *)sdc_textFieldBackgroundViewColor; 221 | + (UIColor *)sdc_dimmedBackgroundColor; 222 | @end 223 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertViewController.m 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 11/5/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import "SDCAlertViewController.h" 10 | 11 | #import "RBBSpringAnimation.h" 12 | #import "SDCAlertView.h" 13 | 14 | #import "UIView+SDCAutoLayout.h" 15 | 16 | #ifndef NSFoundationVersionNumber_iOS_7_1 17 | #define NSFoundationVersionNumber_iOS_7_1 1047.25 18 | #endif 19 | 20 | static CGFloat const SDCAlertViewShowingAnimationScale = 1.26; 21 | static CGFloat const SDCAlertViewDismissingAnimationScale = 0.84; 22 | static CFTimeInterval const SDCAlertViewSpringAnimationDuration = 0.5058237314224243; 23 | static CGFloat const SDCAlertViewSpringAnimationDamping = 500; 24 | static CGFloat const SDCAlertViewSpringAnimationMass = 3; 25 | static CGFloat const SDCAlertViewSpringAnimationStiffness = 1000; 26 | static CGFloat const SDCAlertViewSpringAnimationVelocity = 0; 27 | 28 | @interface UIWindow (SDCAlertView) 29 | + (UIWindow *)sdc_alertWindow; 30 | @end 31 | 32 | @interface SDCAlertViewController () 33 | @property (nonatomic, strong) UIView *alertContainerView; 34 | @property (nonatomic, strong) UIView *dimmingView; 35 | @property (nonatomic) BOOL showsDimmingView; 36 | @property (nonatomic, strong) NSLayoutConstraint *bottomSpacingConstraint; 37 | @property (nonatomic, getter = isPresentingFirstAlert) BOOL presentingFirstAlert; 38 | @property (nonatomic, getter = isDismissingLastAlert) BOOL dismissingLastAlert; 39 | @end 40 | 41 | @implementation SDCAlertViewController 42 | 43 | // UIViewController has a private instance variable named dimmingView. Divert from the convention... 44 | @synthesize dimmingView = dimmingView_; 45 | 46 | - (instancetype)init { 47 | self = [super init]; 48 | 49 | if (self) { 50 | [self createViewHierarchy]; 51 | 52 | _presentingFirstAlert = YES; 53 | 54 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 55 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 56 | } 57 | 58 | return self; 59 | } 60 | 61 | #pragma mark - Status Bar 62 | 63 | - (BOOL)prefersStatusBarHidden { 64 | return [[UIApplication sharedApplication] isStatusBarHidden]; 65 | } 66 | 67 | - (UIStatusBarStyle)preferredStatusBarStyle { 68 | return [[UIApplication sharedApplication] statusBarStyle]; 69 | } 70 | 71 | #pragma mark - View Hierarchy 72 | 73 | - (void)createViewHierarchy { 74 | [self createDimmingView]; 75 | [self createAlertContainer]; 76 | } 77 | 78 | - (void)createDimmingView { 79 | self.dimmingView = [[UIView alloc] initWithFrame:self.alertContainerView.bounds]; 80 | [self.dimmingView setTranslatesAutoresizingMaskIntoConstraints:NO]; 81 | self.dimmingView.backgroundColor = [UIColor sdc_dimmedBackgroundColor]; 82 | [self.view addSubview:self.dimmingView]; 83 | [self.dimmingView sdc_alignEdgesWithSuperview:UIRectEdgeAll]; 84 | } 85 | 86 | - (void)createAlertContainer { 87 | self.alertContainerView = [[UIView alloc] initWithFrame:self.view.bounds]; 88 | [self.alertContainerView setTranslatesAutoresizingMaskIntoConstraints:NO]; 89 | [self.view addSubview:self.alertContainerView]; 90 | [self.alertContainerView sdc_alignEdgesWithSuperview:UIRectEdgeLeft|UIRectEdgeTop|UIRectEdgeRight]; 91 | self.bottomSpacingConstraint = [[self.alertContainerView sdc_alignEdgesWithSuperview:UIRectEdgeBottom] firstObject]; 92 | } 93 | 94 | #pragma mark - Showing/Hiding 95 | 96 | - (void)animateAlertContainerForKeyboardChangeWithDuration:(NSTimeInterval)duration { 97 | [UIView animateWithDuration:duration animations:^{ 98 | [self.view layoutIfNeeded]; 99 | }]; 100 | } 101 | 102 | - (void)keyboardWillShow:(NSNotification *)notification { 103 | CGRect keyboardFrame = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; 104 | UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; 105 | 106 | CGFloat keyboardHeight = CGRectGetHeight(keyboardFrame); 107 | 108 | /* 109 | * Normally, the keyboard's frame would have to be converted using a convertRect: method to get 110 | * the frame in the right orientation. This works in both portrait and landscape if the orientation 111 | * stays the same, but not if the device is rotated when an alert is shown. So we directly check 112 | * the orientation and use either the keyboard frame's width or height based on that. Not great, but it works. 113 | * This problem is fixed in iOS 8, so the hack is only in place for iOS 7. 114 | */ 115 | 116 | if (UIInterfaceOrientationIsLandscape(orientation) && floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { 117 | keyboardHeight = CGRectGetWidth(keyboardFrame); 118 | } 119 | 120 | self.bottomSpacingConstraint.constant = -keyboardHeight; 121 | 122 | // No need to animate the resizing of the alert container when the first alert is presented 123 | if (!self.isPresentingFirstAlert) { 124 | NSTimeInterval animationDuration = [[notification userInfo][UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 125 | [self animateAlertContainerForKeyboardChangeWithDuration:animationDuration]; 126 | } 127 | } 128 | 129 | - (void)keyboardWillHide:(NSNotification *)notification { 130 | /* 131 | * Don't resize the alert container if we're animating the last alert that was going to 132 | * be shown. If an alert showed a keyboard, that keyboard will animate away when the alert 133 | * is dismissed. To make sure the next alert is shown centered, we normally resize the alert 134 | * container so that the next alert is centered. This causes the previous alert's dismissing 135 | * animation to be "warped"--it fades out toward the center of the screen. If a new alert is 136 | * showing, that effect is barely visible due to the new alert covering the old alert. However, 137 | * if there is no new alert, that effect is visible pretty well. That's why we don't resize 138 | * the container if there is no new alert. 139 | */ 140 | 141 | if (!self.isDismissingLastAlert) { 142 | NSDictionary *userInfo = [notification userInfo]; 143 | NSTimeInterval animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 144 | 145 | self.bottomSpacingConstraint.constant = 0; 146 | [self animateAlertContainerForKeyboardChangeWithDuration:animationDuration]; 147 | } 148 | } 149 | 150 | - (void)replaceAlert:(SDCAlertView *)oldAlert 151 | withAlert:(SDCAlertView *)newAlert 152 | animated:(BOOL)animated 153 | completion:(void (^)(void))completionHandler { 154 | self.dismissingLastAlert = newAlert == nil; 155 | [self updateDimmingViewVisibility:!self.isDismissingLastAlert]; 156 | 157 | [self showAlert:newAlert]; 158 | [oldAlert resignFirstResponder]; 159 | 160 | [CATransaction begin]; 161 | [CATransaction setCompletionBlock:^{ 162 | self.presentingFirstAlert = newAlert == nil; 163 | [oldAlert removeFromSuperview]; 164 | 165 | if (completionHandler) 166 | completionHandler(); 167 | }]; 168 | 169 | if (oldAlert && animated) [self applyDismissingAnimationsToAlert:oldAlert]; 170 | if (newAlert) [self applyPresentingAnimationsToAlert:newAlert]; 171 | 172 | [CATransaction commit]; 173 | } 174 | 175 | - (void)showAlert:(SDCAlertView *)alert { 176 | if (alert) { 177 | [alert becomeFirstResponder]; 178 | [self.alertContainerView addSubview:alert]; 179 | } 180 | } 181 | 182 | #pragma mark - Dimming View 183 | 184 | - (void)updateDimmingViewVisibility:(BOOL)show { 185 | if (show && !self.showsDimmingView) 186 | [self showDimmingView]; 187 | else if (!show && self.showsDimmingView) 188 | [self hideDimmingView]; 189 | } 190 | 191 | - (void)showDimmingView { 192 | RBBSpringAnimation *animation = [self opacityAnimationForPresenting]; 193 | self.dimmingView.layer.opacity = 1; 194 | [self.dimmingView.layer addAnimation:animation forKey:@"opacity"]; 195 | 196 | self.showsDimmingView = YES; 197 | } 198 | 199 | - (void)hideDimmingView { 200 | RBBSpringAnimation *animation = [self opacityAnimationForDismissing]; 201 | self.dimmingView.layer.opacity = 0; 202 | [self.dimmingView.layer addAnimation:animation forKey:@"opacity"]; 203 | 204 | self.showsDimmingView = NO; 205 | } 206 | 207 | #pragma mark - Animations 208 | 209 | - (RBBSpringAnimation *)springAnimationForKey:(NSString *)key { 210 | RBBSpringAnimation *animation = [[RBBSpringAnimation alloc] init]; 211 | animation.delegate = self; 212 | 213 | animation.duration = SDCAlertViewSpringAnimationDuration; 214 | animation.damping = SDCAlertViewSpringAnimationDamping; 215 | animation.mass = SDCAlertViewSpringAnimationMass; 216 | animation.stiffness = SDCAlertViewSpringAnimationStiffness; 217 | animation.velocity = SDCAlertViewSpringAnimationVelocity; 218 | 219 | return animation; 220 | } 221 | 222 | #pragma mark - Opacity 223 | 224 | - (RBBSpringAnimation *)opacityAnimationForPresenting { 225 | return [self opacityAnimationFrom:@0 to:@1]; 226 | } 227 | 228 | - (RBBSpringAnimation *)opacityAnimationForDismissing { 229 | return [self opacityAnimationFrom:@1 to:@0]; 230 | } 231 | 232 | - (RBBSpringAnimation *)opacityAnimationFrom:(NSNumber *)from to:(NSNumber *)to { 233 | RBBSpringAnimation *opacityAnimation = [self springAnimationForKey:@"opacity"]; 234 | opacityAnimation.fromValue = from; 235 | opacityAnimation.toValue = to; 236 | 237 | return opacityAnimation; 238 | } 239 | 240 | #pragma mark Transform 241 | 242 | - (RBBSpringAnimation *)transformAnimationForPresenting { 243 | CATransform3D transformFrom = CATransform3DMakeScale(SDCAlertViewShowingAnimationScale, SDCAlertViewShowingAnimationScale, 1); 244 | CATransform3D transformTo = CATransform3DMakeScale(1, 1, 1); 245 | return [self transformAnimationFrom:transformFrom to:transformTo]; 246 | } 247 | 248 | - (RBBSpringAnimation *)transformAnimationForDismissing { 249 | CATransform3D transformFrom = CATransform3DMakeScale(1, 1, 1); 250 | CATransform3D transformTo = CATransform3DMakeScale(SDCAlertViewDismissingAnimationScale, SDCAlertViewDismissingAnimationScale, 1); 251 | return [self transformAnimationFrom:transformFrom to:transformTo]; 252 | } 253 | 254 | - (RBBSpringAnimation *)transformAnimationFrom:(CATransform3D)from to:(CATransform3D)to { 255 | RBBSpringAnimation *transformAnimation = [self springAnimationForKey:@"transform"]; 256 | transformAnimation.fromValue = [NSValue valueWithCATransform3D:from]; 257 | transformAnimation.toValue = [NSValue valueWithCATransform3D:to]; 258 | 259 | return transformAnimation; 260 | } 261 | 262 | #pragma mark Presenting & Dismissing 263 | 264 | - (void)applyPresentingAnimationsToAlert:(SDCAlertView *)alert { 265 | RBBSpringAnimation *opacityAnimation = [self opacityAnimationForPresenting]; 266 | alert.layer.opacity = 1; 267 | [alert.layer addAnimation:opacityAnimation forKey:@"opacity"]; 268 | 269 | RBBSpringAnimation *transformAnimation = [self transformAnimationForPresenting]; 270 | alert.layer.transform = [transformAnimation.toValue CATransform3DValue]; 271 | [alert.layer addAnimation:transformAnimation forKey:@"transform"]; 272 | } 273 | 274 | - (void)applyDismissingAnimationsToAlert:(SDCAlertView *)alert { 275 | RBBSpringAnimation *opacityAnimation = [self opacityAnimationForDismissing]; 276 | alert.layer.opacity = 0; 277 | [alert.layer addAnimation:opacityAnimation forKey:@"opacity"]; 278 | 279 | RBBSpringAnimation *transformAnimation = [self transformAnimationForDismissing]; 280 | [alert.layer addAnimation:transformAnimation forKey:@"transform"]; 281 | } 282 | 283 | - (void)dealloc { 284 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 285 | } 286 | 287 | @end 288 | -------------------------------------------------------------------------------- /Pods/SDCAutoLayout/AutoLayout/UIView+SDCAutoLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SDCAutoLayout.m 3 | // AutoLayout 4 | // 5 | // Created by Scott Berrevoets on 10/18/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import "UIView+SDCAutoLayout.h" 10 | 11 | CGFloat const SDCAutoLayoutStandardSiblingDistance = 8; 12 | CGFloat const SDCAutoLayoutStandardParentChildDistance = 20; 13 | 14 | @implementation UIView (SDCAutoLayout) 15 | 16 | - (UIView *)sdc_commonAncestorWithView:(UIView *)view { 17 | if ([view isDescendantOfView:self]) 18 | return self; 19 | 20 | if ([self isDescendantOfView:view]) 21 | return view; 22 | 23 | UIView *commonAncestor; 24 | 25 | UIView *superview = self.superview; 26 | while (![view isDescendantOfView:superview]) { 27 | superview = superview.superview; 28 | 29 | if (!superview) 30 | break; 31 | } 32 | 33 | commonAncestor = superview; 34 | 35 | return commonAncestor; 36 | } 37 | 38 | #pragma mark - Edge Alignment 39 | 40 | - (NSArray *)sdc_alignEdgesWithSuperview:(UIRectEdge)edges { 41 | return [self sdc_alignEdgesWithSuperview:edges insets:UIEdgeInsetsZero]; 42 | } 43 | 44 | - (NSArray *)sdc_alignEdgesWithSuperview:(UIRectEdge)edges insets:(UIEdgeInsets)insets { 45 | return [self sdc_alignEdges:edges withView:self.superview insets:insets]; 46 | } 47 | 48 | - (NSArray *)sdc_alignEdges:(UIRectEdge)edges withView:(UIView *)view { 49 | return [self sdc_alignEdges:edges withView:view insets:UIEdgeInsetsZero]; 50 | } 51 | 52 | - (NSArray *)sdc_alignEdges:(UIRectEdge)edges withView:(UIView *)view insets:(UIEdgeInsets)insets { 53 | NSMutableArray *constraints = [NSMutableArray array]; 54 | 55 | if (edges & UIRectEdgeTop) [constraints addObject:[self sdc_alignEdge:UIRectEdgeTop withView:view inset:insets.top]]; 56 | if (edges & UIRectEdgeRight) [constraints addObject:[self sdc_alignEdge:UIRectEdgeRight withView:view inset:insets.right]]; 57 | if (edges & UIRectEdgeBottom) [constraints addObject:[self sdc_alignEdge:UIRectEdgeBottom withView:view inset:insets.bottom]]; 58 | if (edges & UIRectEdgeLeft) [constraints addObject:[self sdc_alignEdge:UIRectEdgeLeft withView:view inset:insets.left]]; 59 | 60 | return constraints; 61 | } 62 | 63 | - (NSLayoutConstraint *)sdc_alignEdge:(UIRectEdge)edge withView:(UIView *)view inset:(CGFloat)inset { 64 | return [self sdc_alignEdge:edge withEdge:edge ofView:view inset:inset]; 65 | } 66 | 67 | - (NSLayoutAttribute)sdc_layoutAttributeFromRectEdge:(UIRectEdge)edge { 68 | NSLayoutAttribute attribute = NSLayoutAttributeNotAnAttribute; 69 | switch (edge) { 70 | case UIRectEdgeTop: attribute = NSLayoutAttributeTop; break; 71 | case UIRectEdgeRight: attribute = NSLayoutAttributeRight; break; 72 | case UIRectEdgeBottom: attribute = NSLayoutAttributeBottom; break; 73 | case UIRectEdgeLeft: attribute = NSLayoutAttributeLeft; break; 74 | default: break; 75 | } 76 | 77 | return attribute; 78 | } 79 | 80 | - (NSLayoutConstraint *)sdc_alignEdge:(UIRectEdge)edge withEdge:(UIRectEdge)otherEdge ofView:(UIView *)view { 81 | return [self sdc_alignEdge:edge withEdge:otherEdge ofView:view inset:0]; 82 | } 83 | 84 | - (NSLayoutConstraint *)sdc_alignEdge:(UIRectEdge)edge withEdge:(UIRectEdge)otherEdge ofView:(UIView *)view inset:(CGFloat)inset { 85 | UIView *commonAncestor = [self sdc_commonAncestorWithView:view]; 86 | 87 | NSLayoutAttribute attribute = [self sdc_layoutAttributeFromRectEdge:edge]; 88 | NSLayoutAttribute otherAttribute = [self sdc_layoutAttributeFromRectEdge:otherEdge]; 89 | 90 | if (attribute == NSLayoutAttributeNotAnAttribute || otherAttribute == NSLayoutAttributeNotAnAttribute) 91 | return nil; 92 | 93 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:attribute relatedBy:NSLayoutRelationEqual toItem:view attribute:otherAttribute multiplier:1 constant:inset]; 94 | [commonAncestor addConstraint:constraint]; 95 | 96 | return constraint; 97 | } 98 | 99 | #pragma mark - Center Alignment 100 | 101 | - (NSArray *)sdc_alignCentersWithView:(UIView *)view { 102 | return [self sdc_alignCentersWithView:view]; 103 | } 104 | 105 | - (NSArray *)sdc_alignCentersWithView:(UIView *)view offset:(UIOffset)offset { 106 | return @[[self sdc_alignHorizontalCenterWithView:view offset:offset.horizontal], [self sdc_alignVerticalCenterWithView:view offset:offset.vertical]]; 107 | } 108 | 109 | - (NSLayoutConstraint *)sdc_alignHorizontalCenterWithView:(UIView *)view { 110 | return [self sdc_alignHorizontalCenterWithView:view offset:UIOffsetZero.horizontal]; 111 | } 112 | 113 | - (NSLayoutConstraint *)sdc_alignHorizontalCenterWithView:(UIView *)view offset:(CGFloat)offset { 114 | UIView *commonAncestor = [self sdc_commonAncestorWithView:view]; 115 | 116 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeCenterX multiplier:1 constant:offset]; 117 | [commonAncestor addConstraint:constraint]; 118 | 119 | return constraint; 120 | } 121 | 122 | - (NSLayoutConstraint *)sdc_alignVerticalCenterWithView:(UIView *)view { 123 | return [self sdc_alignVerticalCenterWithView:view offset:UIOffsetZero.vertical]; 124 | } 125 | 126 | - (NSLayoutConstraint *)sdc_alignVerticalCenterWithView:(UIView *)view offset:(CGFloat)offset { 127 | UIView *commonAncestor = [self sdc_commonAncestorWithView:view]; 128 | 129 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeCenterY multiplier:1 constant:offset]; 130 | [commonAncestor addConstraint:constraint]; 131 | 132 | return constraint; 133 | } 134 | 135 | #pragma mark Superview 136 | 137 | - (NSArray *)sdc_centerInSuperview { 138 | return [self sdc_centerInSuperviewWithOffset:UIOffsetZero]; 139 | } 140 | 141 | - (NSArray *)sdc_centerInSuperviewWithOffset:(UIOffset)offset { 142 | return @[[self sdc_horizontallyCenterInSuperviewWithOffset:offset.horizontal], 143 | [self sdc_verticallyCenterInSuperviewWithOffset:offset.vertical]]; 144 | } 145 | 146 | - (NSLayoutConstraint *)sdc_horizontallyCenterInSuperview { 147 | return [self sdc_horizontallyCenterInSuperviewWithOffset:0]; 148 | } 149 | 150 | - (NSLayoutConstraint *)sdc_horizontallyCenterInSuperviewWithOffset:(CGFloat)offset { 151 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterX multiplier:1 constant:offset]; 152 | [self.superview addConstraint:constraint]; 153 | 154 | return constraint; 155 | } 156 | 157 | - (NSLayoutConstraint *)sdc_verticallyCenterInSuperview { 158 | return [self sdc_verticallyCenterInSuperviewWithOffset:0]; 159 | } 160 | 161 | - (NSLayoutConstraint *)sdc_verticallyCenterInSuperviewWithOffset:(CGFloat)offset { 162 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:offset]; 163 | 164 | [self.superview addConstraint:constraint]; 165 | return constraint; 166 | } 167 | 168 | #pragma mark - Baseline Alignment 169 | 170 | - (NSLayoutConstraint *)sdc_alignBaselineWithView:(UIView *)view { 171 | return [self sdc_alignBaselineWithView:view offset:0]; 172 | } 173 | - (NSLayoutConstraint *)sdc_alignBaselineWithView:(UIView *)view offset:(CGFloat)offset { 174 | UIView *commonAncestor = [self sdc_commonAncestorWithView:view]; 175 | 176 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBaseline relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBaseline multiplier:1 constant:offset]; 177 | [commonAncestor addConstraint:constraint]; 178 | 179 | return constraint; 180 | } 181 | 182 | #pragma mark - Pinning Constants 183 | 184 | - (NSLayoutConstraint *)sdc_pinWidth:(CGFloat)width { 185 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:width]; 186 | [self addConstraint:constraint]; 187 | 188 | return constraint; 189 | } 190 | 191 | - (NSLayoutConstraint *)sdc_setMinimumWidth:(CGFloat)minimumWidth { 192 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:minimumWidth]; 193 | [self addConstraint:constraint]; 194 | 195 | return constraint; 196 | } 197 | 198 | - (NSLayoutConstraint *)sdc_setMaximumWidth:(CGFloat)maximumWidth { 199 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:maximumWidth]; 200 | [self addConstraint:constraint]; 201 | 202 | return constraint; 203 | } 204 | 205 | - (NSLayoutConstraint *)sdc_setMaximumWidthToSuperviewWidth { 206 | return [self sdc_setMaximumWidthToSuperviewWidthWithOffset:0]; 207 | } 208 | 209 | - (NSLayoutConstraint *)sdc_setMaximumWidthToSuperviewWidthWithOffset:(CGFloat)offset { 210 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:self.superview attribute:NSLayoutAttributeWidth multiplier:1 constant:offset]; 211 | [self.superview addConstraint:constraint]; 212 | 213 | return constraint; 214 | } 215 | 216 | - (NSLayoutConstraint *)sdc_pinHeight:(CGFloat)height { 217 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:height]; 218 | [self addConstraint:constraint]; 219 | 220 | return constraint; 221 | } 222 | 223 | - (NSLayoutConstraint *)sdc_setMinimumHeight:(CGFloat)minimumHeight { 224 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:minimumHeight]; 225 | [self addConstraint:constraint]; 226 | 227 | return constraint; 228 | } 229 | 230 | - (NSLayoutConstraint *)sdc_setMaximumHeight:(CGFloat)maximumHeight { 231 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:maximumHeight]; 232 | [self addConstraint:constraint]; 233 | 234 | return constraint; 235 | } 236 | 237 | - (NSLayoutConstraint *)sdc_setMaximumHeightToSuperviewHeight { 238 | return [self sdc_setMaximumHeightToSuperviewHeightWithOffset:0]; 239 | } 240 | 241 | - (NSLayoutConstraint *)sdc_setMaximumHeightToSuperviewHeightWithOffset:(CGFloat)offset { 242 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationLessThanOrEqual toItem:self.superview attribute:NSLayoutAttributeHeight multiplier:1 constant:offset]; 243 | [self.superview addConstraint:constraint]; 244 | 245 | return constraint; 246 | } 247 | 248 | - (NSArray *)sdc_pinSize:(CGSize)size { 249 | return @[[self sdc_pinWidth:size.width], [self sdc_pinHeight:size.height]]; 250 | } 251 | 252 | #pragma mark - Pinning Views 253 | 254 | - (NSLayoutConstraint *)sdc_pinWidthToWidthOfView:(UIView *)view { 255 | return [self sdc_pinWidthToWidthOfView:view offset:0]; 256 | } 257 | 258 | - (NSLayoutConstraint *)sdc_pinWidthToWidthOfView:(UIView *)view offset:(CGFloat)offset { 259 | UIView *commonAncestor = [self sdc_commonAncestorWithView:view]; 260 | 261 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeWidth multiplier:1 constant:offset]; 262 | [commonAncestor addConstraint:constraint]; 263 | 264 | return constraint; 265 | } 266 | 267 | - (NSLayoutConstraint *)sdc_pinHeightToHeightOfView:(UIView *)view { 268 | return [self sdc_pinHeightToHeightOfView:view offset:0]; 269 | } 270 | 271 | - (NSLayoutConstraint *)sdc_pinHeightToHeightOfView:(UIView *)view offset:(CGFloat)offset { 272 | UIView *commonAncestor = [self sdc_commonAncestorWithView:view]; 273 | 274 | NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeHeight multiplier:1 constant:offset]; 275 | [commonAncestor addConstraint:constraint]; 276 | 277 | return constraint; 278 | } 279 | 280 | - (NSArray *)sdc_pinSizeToSizeOfView:(UIView *)view { 281 | return [self sdc_pinSizeToSizeOfView:view offset:UIOffsetZero]; 282 | } 283 | 284 | - (NSArray *)sdc_pinSizeToSizeOfView:(UIView *)view offset:(UIOffset)offset { 285 | return @[[self sdc_pinWidthToWidthOfView:view offset:offset.horizontal], [self sdc_pinHeightToHeightOfView:view offset:offset.vertical]]; 286 | } 287 | 288 | #pragma mark - Pinning Spacing 289 | 290 | - (NSLayoutConstraint *)sdc_pinHorizontalSpacing:(CGFloat)spacing toView:(UIView *)view { 291 | UIView *commonAncestor = [self sdc_commonAncestorWithView:view]; 292 | 293 | NSLayoutConstraint *constraint; 294 | 295 | if (spacing >= 0) { 296 | constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeRight multiplier:1 constant:spacing]; 297 | } else { 298 | constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeft multiplier:1 constant:abs(spacing)]; 299 | } 300 | 301 | [commonAncestor addConstraint:constraint]; 302 | return constraint; 303 | } 304 | 305 | - (NSLayoutConstraint *)sdc_pinVerticalSpacing:(CGFloat)spacing toView:(UIView *)view { 306 | UIView *commonAncestor = [self sdc_commonAncestorWithView:view]; 307 | 308 | NSLayoutConstraint *constraint; 309 | 310 | if (spacing >= 0) { 311 | constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBottom multiplier:1 constant:spacing]; 312 | } else { 313 | constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTop multiplier:1 constant:abs(spacing)]; 314 | } 315 | 316 | [commonAncestor addConstraint:constraint]; 317 | return constraint; 318 | } 319 | 320 | - (NSArray *)sdc_pinSpacing:(UIOffset)spacing toView:(UIView *)view { 321 | return @[[self sdc_pinHorizontalSpacing:spacing.horizontal toView:view], [self sdc_pinVerticalSpacing:spacing.vertical toView:view]]; 322 | } 323 | 324 | @end 325 | -------------------------------------------------------------------------------- /SDCAlertView/Source/SDCAlertView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDCAlertView.m 3 | // SDCAlertView 4 | // 5 | // Created by Scott Berrevoets on 9/20/13. 6 | // Copyright (c) 2013 Scotty Doesn't Code. All rights reserved. 7 | // 8 | 9 | #import "SDCAlertView.h" 10 | 11 | #import "SDCAlertViewController.h" 12 | #import "SDCAlertViewCoordinator.h" 13 | #import "SDCAlertViewBackgroundView.h" 14 | #import "SDCAlertViewContentView.h" 15 | 16 | #import "UIView+SDCAutoLayout.h" 17 | 18 | CGFloat const SDCAlertViewWidth = 270; 19 | static UIEdgeInsets const SDCAlertViewPadding = {3, 0, 3, 0}; 20 | static CGFloat const SDCAlertViewCornerRadius = 7; 21 | 22 | static UIOffset const SDCAlertViewParallaxSlideMagnitude = {15.75, 15.75}; 23 | 24 | #pragma mark - SDCAlertView 25 | 26 | @interface SDCAlertView () 27 | @property (nonatomic, strong) id transitionCoordinator; 28 | @property (nonatomic, strong) SDCAlertViewBackgroundView *alertBackgroundView; 29 | @property (nonatomic, strong) SDCAlertViewContentView *alertContentView; 30 | @end 31 | 32 | @implementation SDCAlertView 33 | 34 | #pragma mark - UIAppearance 35 | 36 | + (void)initialize { 37 | [super initialize]; 38 | 39 | SDCAlertView *appearance = [self appearance]; 40 | 41 | [appearance setTitleLabelFont:[UIFont boldSystemFontOfSize:17]]; 42 | [appearance setMessageLabelFont:[UIFont systemFontOfSize:14]]; 43 | [appearance setTextFieldFont:[UIFont systemFontOfSize:13]]; 44 | [appearance setSuggestedButtonFont:[UIFont boldSystemFontOfSize:17]]; 45 | [appearance setNormalButtonFont:[UIFont systemFontOfSize:17]]; 46 | [appearance setTextFieldTextColor:[UIColor darkTextColor]]; 47 | [appearance setTitleLabelTextColor:[UIColor darkTextColor]]; 48 | [appearance setMessageLabelTextColor:[UIColor darkTextColor]]; 49 | } 50 | 51 | #pragma mark - Lazy Instantiation 52 | 53 | - (SDCAlertViewBackgroundView *)alertBackgroundView { 54 | if (!_alertBackgroundView) { 55 | _alertBackgroundView = [[SDCAlertViewBackgroundView alloc] init]; 56 | [_alertBackgroundView setTranslatesAutoresizingMaskIntoConstraints:NO]; 57 | } 58 | 59 | return _alertBackgroundView; 60 | } 61 | 62 | - (SDCAlertViewContentView *)alertContentView { 63 | if (!_alertContentView) { 64 | _alertContentView = [[SDCAlertViewContentView alloc] initWithDelegate:self]; 65 | [_alertContentView setTranslatesAutoresizingMaskIntoConstraints:NO]; 66 | } 67 | 68 | return _alertContentView; 69 | } 70 | 71 | - (id )transitionCoordinator { 72 | return (_transitionCoordinator) ? _transitionCoordinator : [SDCAlertViewCoordinator sharedCoordinator]; 73 | } 74 | 75 | #pragma mark - Initialization 76 | 77 | - (id)init { 78 | return [self initWithTitle:nil message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil]; 79 | } 80 | 81 | - (instancetype)initWithTitle:(NSString *)title 82 | message:(NSString *)message 83 | delegate:(id)delegate 84 | cancelButtonTitle:(NSString *)cancelButtonTitle 85 | otherButtonTitles:(NSString *)otherButtonTitles, ... { 86 | self = [super init]; 87 | 88 | if (self) { 89 | [self setTranslatesAutoresizingMaskIntoConstraints:NO]; 90 | 91 | [self addParallaxEffect]; 92 | 93 | self.layer.masksToBounds = YES; 94 | self.layer.cornerRadius = SDCAlertViewCornerRadius; 95 | 96 | _delegate = delegate; 97 | 98 | [self createContentViewWithTitle:title message:message]; 99 | self.alertContentView.cancelButtonTitle = cancelButtonTitle; 100 | 101 | va_list argumentList; 102 | va_start(argumentList, otherButtonTitles); 103 | for (NSString *buttonTitle = otherButtonTitles; buttonTitle != nil; buttonTitle = va_arg(argumentList, NSString *)) 104 | [self.alertContentView addButtonWithTitle:buttonTitle]; 105 | } 106 | 107 | return self; 108 | } 109 | 110 | - (void)addParallaxEffect { 111 | UIInterpolatingMotionEffect *horizontalParallax; 112 | UIInterpolatingMotionEffect *verticalParallax; 113 | 114 | horizontalParallax = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; 115 | horizontalParallax.minimumRelativeValue = @(-SDCAlertViewParallaxSlideMagnitude.horizontal); 116 | horizontalParallax.maximumRelativeValue = @(SDCAlertViewParallaxSlideMagnitude.horizontal); 117 | 118 | verticalParallax = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; 119 | verticalParallax.minimumRelativeValue = @(-SDCAlertViewParallaxSlideMagnitude.vertical); 120 | verticalParallax.maximumRelativeValue = @(SDCAlertViewParallaxSlideMagnitude.vertical); 121 | 122 | UIMotionEffectGroup *groupMotionEffect = [[UIMotionEffectGroup alloc] init]; 123 | groupMotionEffect.motionEffects = @[horizontalParallax, verticalParallax]; 124 | [self addMotionEffect:groupMotionEffect]; 125 | } 126 | 127 | #pragma mark - Visibility 128 | 129 | - (BOOL)isVisible { 130 | return self.transitionCoordinator.visibleAlert == self; 131 | } 132 | 133 | #pragma mark - Presenting 134 | 135 | - (void)show { 136 | [self updateFirstButtonEnabledStatus]; 137 | [self monitorChangesForTextFields:self.alertContentView.textFields]; 138 | 139 | [self.alertContentView prepareForShowing]; 140 | 141 | [self addSubview:self.alertBackgroundView]; 142 | [self addSubview:self.alertContentView]; 143 | 144 | [self.transitionCoordinator presentAlert:self]; 145 | } 146 | 147 | - (void)willBePresented { 148 | if ([self.delegate respondsToSelector:@selector(willPresentAlertView:)]) 149 | [self.delegate willPresentAlertView:self]; 150 | } 151 | 152 | - (void)wasPresented { 153 | if ([self.delegate respondsToSelector:@selector(didPresentAlertView:)]) 154 | [self.delegate didPresentAlertView:self]; 155 | } 156 | 157 | #pragma mark - Dismissing 158 | 159 | - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { 160 | [self.transitionCoordinator dismissAlert:self withButtonIndex:buttonIndex animated:animated]; 161 | } 162 | 163 | - (void)willBeDismissedWithButtonIndex:(NSInteger)buttonIndex { 164 | if ([self.delegate respondsToSelector:@selector(alertView:willDismissWithButtonIndex:)]) 165 | [self.delegate alertView:self willDismissWithButtonIndex:buttonIndex]; 166 | 167 | if (self.willDismissHandler) 168 | self.willDismissHandler(buttonIndex); 169 | } 170 | 171 | - (void)wasDismissedWithButtonIndex:(NSInteger)buttonIndex { 172 | if ([self.delegate respondsToSelector:@selector(alertView:didDismissWithButtonIndex:)]) 173 | [self.delegate alertView:self didDismissWithButtonIndex:buttonIndex]; 174 | 175 | if (self.didDismissHandler) 176 | self.didDismissHandler(buttonIndex); 177 | } 178 | 179 | #pragma mark - First Responder 180 | 181 | - (BOOL)becomeFirstResponder { 182 | [super becomeFirstResponder]; 183 | [self.alertContentView becomeFirstResponder]; 184 | 185 | return YES; 186 | } 187 | 188 | - (BOOL)resignFirstResponder { 189 | [super resignFirstResponder]; 190 | [self.alertContentView resignFirstResponder]; 191 | 192 | return YES; 193 | } 194 | 195 | #pragma mark - Title & Message Labels 196 | 197 | - (NSString *)title { 198 | return self.alertContentView.title; 199 | } 200 | 201 | - (void)setTitle:(NSString *)title { 202 | self.alertContentView.title = title; 203 | } 204 | 205 | - (NSAttributedString *)attributedTitle { 206 | return self.alertContentView.attributedTitle; 207 | } 208 | 209 | - (void)setAttributedTitle:(NSAttributedString *)attributedTitle { 210 | self.alertContentView.attributedTitle = attributedTitle; 211 | } 212 | 213 | - (NSString *)message { 214 | return self.alertContentView.message; 215 | } 216 | 217 | - (void)setMessage:(NSString *)message { 218 | self.alertContentView.message = message; 219 | } 220 | 221 | - (NSAttributedString *)attributedMessage { 222 | return self.alertContentView.attributedMessage; 223 | } 224 | 225 | - (void)setAttributedMessage:(NSAttributedString *)attributedMessage { 226 | self.alertContentView.attributedMessage = attributedMessage; 227 | } 228 | 229 | #pragma mark - Content 230 | 231 | - (void)setAlertViewStyle:(SDCAlertViewStyle)alertViewStyle { 232 | _alertViewStyle = alertViewStyle; 233 | [self.alertContentView updateContentForStyle:alertViewStyle]; 234 | } 235 | 236 | - (BOOL)alwaysShowsButtonsVertically { 237 | return self.alertContentView.alwaysShowsButtonsVertically; 238 | } 239 | 240 | - (void)setAlwaysShowsButtonsVertically:(BOOL)alwaysShowsButtonsVertically { 241 | self.alertContentView.alwaysShowsButtonsVertically = alwaysShowsButtonsVertically; 242 | } 243 | 244 | - (UIView *)contentView { 245 | return self.alertContentView.customContentView; 246 | } 247 | 248 | - (void)createContentViewWithTitle:(NSString *)title message:(NSString *)message { 249 | self.alertContentView.title = title; 250 | self.alertContentView.message = message; 251 | [self.alertContentView updateContentForStyle:self.alertViewStyle]; 252 | } 253 | 254 | - (void)monitorChangesForTextFields:(NSArray *)textFields { 255 | [textFields enumerateObjectsUsingBlock:^(UITextField *textField, NSUInteger idx, BOOL *stop) { 256 | [textField addTarget:self action:@selector(updateFirstButtonEnabledStatus) forControlEvents:UIControlEventEditingChanged]; 257 | }]; 258 | } 259 | 260 | - (void)updateFirstButtonEnabledStatus { 261 | if ([self.delegate respondsToSelector:@selector(alertViewShouldEnableFirstOtherButton:)]) 262 | self.alertContentView.firstOtherButtonEnabled = [self.delegate alertViewShouldEnableFirstOtherButton:self]; 263 | } 264 | 265 | #pragma mark - SDCAlertViewContentViewDelegate 266 | 267 | - (BOOL)alertContentView:(SDCAlertViewContentView *)sender shouldDeselectButtonAtIndex:(NSUInteger)index { 268 | if ([self.delegate respondsToSelector:@selector(alertView:shouldDeselectButtonAtIndex:)]) 269 | return [self.delegate alertView:self shouldDeselectButtonAtIndex:index]; 270 | else if (self.shouldDeselectButtonHandler) 271 | return self.shouldDeselectButtonHandler(index); 272 | 273 | return YES; 274 | } 275 | 276 | - (void)alertContentView:(SDCAlertViewContentView *)sender didTapButtonAtIndex:(NSUInteger)index { 277 | [self tappedButtonAtIndex:index]; 278 | } 279 | 280 | #pragma mark - Buttons & Text Fields 281 | 282 | - (NSInteger)cancelButtonIndex { 283 | return self.alertContentView.cancelButtonIndex; 284 | } 285 | 286 | - (void)setCancelButtonIndex:(NSInteger)cancelButtonIndex { 287 | self.alertContentView.cancelButtonIndex = cancelButtonIndex; 288 | } 289 | 290 | - (NSInteger)firstOtherButtonIndex { 291 | return self.alertContentView.firstOtherButtonIndex; 292 | } 293 | 294 | - (NSInteger)numberOfButtons { 295 | return self.alertContentView.numberOfButtons; 296 | } 297 | 298 | - (void)tappedButtonAtIndex:(NSInteger)index { 299 | if ([self.delegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) 300 | [self.delegate alertView:self clickedButtonAtIndex:index]; 301 | 302 | if (self.clickedButtonHandler) 303 | self.clickedButtonHandler(index); 304 | 305 | if ([self.delegate respondsToSelector:@selector(alertView:shouldDismissWithButtonIndex:)]) { 306 | if ([self.delegate alertView:self shouldDismissWithButtonIndex:index]) 307 | [self dismissWithClickedButtonIndex:index animated:YES]; 308 | } else if (self.shouldDismissHandler) { 309 | if (self.shouldDismissHandler(index)) 310 | [self dismissWithClickedButtonIndex:index animated:YES]; 311 | } else { 312 | [self dismissWithClickedButtonIndex:index animated:YES]; 313 | } 314 | } 315 | 316 | - (NSInteger)addButtonWithTitle:(NSString *)title { 317 | return [self.alertContentView addButtonWithTitle:title]; 318 | } 319 | 320 | - (NSString *)buttonTitleAtIndex:(NSInteger)index { 321 | return [self.alertContentView buttonTitleAtIndex:index]; 322 | } 323 | 324 | - (UITextField *)textFieldAtIndex:(NSInteger)textFieldIndex { 325 | return self.alertContentView.textFields[textFieldIndex]; 326 | } 327 | 328 | #pragma mark - Layout 329 | 330 | - (void)willMoveToSuperview:(UIView *)newSuperview { 331 | if (newSuperview) 332 | [self setNeedsUpdateConstraints]; // Recalculate the alert's dimensions based on the alert's new superview 333 | } 334 | 335 | - (void)layoutSubviews { 336 | [super layoutSubviews]; 337 | self.alertContentView.maximumSize = CGSizeMake(SDCAlertViewWidth, CGRectGetHeight(self.superview.bounds) - SDCAlertViewPadding.top - SDCAlertViewPadding.bottom); 338 | [self.alertContentView setNeedsUpdateConstraints]; 339 | } 340 | 341 | - (void)updateConstraints { 342 | [self removeConstraints:[self constraints]]; 343 | 344 | [self.alertBackgroundView sdc_centerInSuperview]; 345 | [self.alertBackgroundView sdc_pinWidthToWidthOfView:self]; 346 | [self.alertBackgroundView sdc_pinHeightToHeightOfView:self]; 347 | 348 | [self.alertContentView sdc_centerInSuperview]; 349 | [self.alertContentView sdc_pinWidthToWidthOfView:self]; 350 | [self.alertContentView sdc_pinHeightToHeightOfView:self]; 351 | 352 | [self positionSelf]; 353 | 354 | [super updateConstraints]; 355 | } 356 | 357 | - (void)positionSelf { 358 | [self sdc_pinWidth:SDCAlertViewWidth]; 359 | [self sdc_centerInSuperview]; 360 | } 361 | 362 | @end 363 | 364 | @implementation SDCAlertView (Convenience) 365 | 366 | - (void)showWithDismissHandler:(void (^)(NSInteger))dismissHandler { 367 | self.didDismissHandler = dismissHandler; 368 | [self show]; 369 | } 370 | 371 | + (instancetype)alertWithTitle:(NSString *)title message:(NSString *)message { 372 | return [self alertWithTitle:title message:message buttons:nil]; 373 | } 374 | 375 | + (instancetype)alertWithTitle:(NSString *)title message:(NSString *)message buttons:(NSArray *)buttons { 376 | return [self alertWithTitle:title message:message subview:nil buttons:buttons]; 377 | } 378 | 379 | + (instancetype)alertWithSubview:(UIView *)subview { 380 | return [self alertWithTitle:nil message:nil subview:subview]; 381 | } 382 | 383 | + (instancetype)alertWithTitle:(NSString *)title subview:(UIView *)subview { 384 | return [self alertWithTitle:title message:nil subview:subview]; 385 | } 386 | 387 | + (instancetype)alertWithTitle:(NSString *)title message:(NSString *)message subview:(UIView *)subview { 388 | return [self alertWithTitle:title message:message subview:subview buttons:nil]; 389 | } 390 | 391 | + (instancetype)alertWithTitle:(NSString *)title message:(NSString *)message subview:(UIView *)subview buttons:(NSArray *)buttons { 392 | SDCAlertView *alert = [[SDCAlertView alloc] initWithTitle:title 393 | message:message 394 | delegate:nil 395 | cancelButtonTitle:[buttons firstObject] 396 | otherButtonTitles:nil]; 397 | 398 | for (int i = 1; i < [buttons count]; i++) 399 | [alert addButtonWithTitle:buttons[i]]; 400 | 401 | if (subview) 402 | [alert.contentView addSubview:subview]; 403 | 404 | [alert show]; 405 | return alert; 406 | } 407 | 408 | @end 409 | 410 | @implementation SDCAlertView (UIAppearance) 411 | 412 | - (BOOL)attributedString:(NSAttributedString *)string hasAttribute:(NSString *)attribute { 413 | NSRange range = NSMakeRange(0, [string length]); 414 | 415 | __block BOOL hasAttribute = NO; 416 | [string enumerateAttribute:attribute inRange:range options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { 417 | if (value) { 418 | hasAttribute = YES; 419 | *stop = YES; 420 | } 421 | }]; 422 | 423 | return hasAttribute; 424 | } 425 | 426 | - (UIFont *)titleLabelFont { 427 | return self.alertContentView.titleLabelFont; 428 | } 429 | 430 | - (void)setTitleLabelFont:(UIFont *)titleLabelFont { 431 | if (![self attributedString:self.attributedTitle hasAttribute:NSFontAttributeName]) 432 | self.alertContentView.titleLabelFont = titleLabelFont; 433 | } 434 | 435 | - (UIColor *)titleLabelTextColor { 436 | return self.alertContentView.titleLabelTextColor; 437 | } 438 | 439 | - (void)setTitleLabelTextColor:(UIColor *)titleLabelTextColor { 440 | if (![self attributedString:self.attributedTitle hasAttribute:NSForegroundColorAttributeName]) 441 | self.alertContentView.titleLabelTextColor = titleLabelTextColor; 442 | } 443 | 444 | - (UIFont *)messageLabelFont { 445 | return self.alertContentView.messageLabelFont; 446 | } 447 | 448 | - (void)setMessageLabelFont:(UIFont *)messageLabelFont { 449 | if (![self attributedString:self.attributedMessage hasAttribute:NSFontAttributeName]) 450 | self.alertContentView.messageLabelFont = messageLabelFont; 451 | } 452 | 453 | - (UIColor *)messageLabelTextColor { 454 | return self.alertContentView.messageLabelTextColor; 455 | } 456 | 457 | - (void)setMessageLabelTextColor:(UIColor *)messageLabelTextColor { 458 | if (![self attributedString:self.attributedMessage hasAttribute:NSForegroundColorAttributeName]) 459 | self.alertContentView.messageLabelTextColor = messageLabelTextColor; 460 | } 461 | 462 | - (UIFont *)textFieldFont { 463 | return self.alertContentView.textFieldFont; 464 | } 465 | 466 | - (void)setTextFieldFont:(UIFont *)textFieldFont { 467 | self.alertContentView.textFieldFont = textFieldFont; 468 | } 469 | 470 | - (UIColor *)textFieldTextColor { 471 | return self.alertContentView.textFieldTextColor; 472 | } 473 | 474 | - (void)setTextFieldTextColor:(UIColor *)textFieldTextColor { 475 | self.alertContentView.textFieldTextColor = textFieldTextColor; 476 | } 477 | 478 | - (UIFont *)suggestedButtonFont { 479 | return self.alertContentView.suggestedButtonFont; 480 | } 481 | 482 | - (void)setSuggestedButtonFont:(UIFont *)suggestedButtonFont { 483 | self.alertContentView.suggestedButtonFont = suggestedButtonFont; 484 | } 485 | 486 | - (UIFont *)normalButtonFont { 487 | return self.alertContentView.normalButtonFont; 488 | } 489 | 490 | - (void)setNormalButtonFont:(UIFont *)normalButtonFont { 491 | self.alertContentView.normalButtonFont = normalButtonFont; 492 | } 493 | 494 | - (UIColor *)buttonTextColor { 495 | return self.alertContentView.buttonTextColor; 496 | } 497 | 498 | - (void)setButtonTextColor:(UIColor *)buttonTextColor { 499 | self.alertContentView.buttonTextColor = buttonTextColor; 500 | } 501 | 502 | @end 503 | 504 | @implementation UIColor (SDCAlertViewColors) 505 | 506 | + (UIColor *)sdc_alertSeparatorColor { 507 | return [UIColor colorWithWhite:0.5 alpha:0.5]; 508 | } 509 | 510 | + (UIColor *)sdc_textFieldBackgroundViewColor { 511 | return [UIColor colorWithWhite:0.5 alpha:0.5]; 512 | } 513 | 514 | + (UIColor *)sdc_dimmedBackgroundColor { 515 | return [UIColor colorWithWhite:0 alpha:.4]; 516 | } 517 | 518 | @end 519 | -------------------------------------------------------------------------------- /SDCAlertView/iPad.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 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /SDCAlertView/Base.lproj/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 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | --------------------------------------------------------------------------------