├── .gitignore ├── Example └── Xcode5 iOS 7 Example │ └── Xcode5Example │ ├── Podfile │ ├── Podfile.lock │ ├── Pods │ ├── Headers │ │ ├── Private │ │ │ └── MZAppearance │ │ │ │ ├── MZAppearance.h │ │ │ │ └── NSInvocation+Copy.h │ │ └── Public │ │ │ └── MZAppearance │ │ │ ├── MZAppearance.h │ │ │ └── NSInvocation+Copy.h │ ├── MZAppearance │ │ ├── LICENSE │ │ ├── MZAppearance │ │ │ ├── MZAppearance.h │ │ │ ├── MZAppearance.m │ │ │ ├── NSInvocation+Copy.h │ │ │ └── NSInvocation+Copy.m │ │ └── README.md │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ └── Target Support Files │ │ ├── Pods-MZAppearance │ │ ├── Pods-MZAppearance-Private.xcconfig │ │ ├── Pods-MZAppearance-dummy.m │ │ ├── Pods-MZAppearance-prefix.pch │ │ └── Pods-MZAppearance.xcconfig │ │ └── Pods │ │ ├── Pods-acknowledgements.markdown │ │ ├── Pods-acknowledgements.plist │ │ ├── Pods-dummy.m │ │ ├── Pods-environment.h │ │ ├── Pods-resources.sh │ │ ├── Pods.debug.xcconfig │ │ └── Pods.release.xcconfig │ ├── Xcode5Example.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── Xcode5Example.xccheckout │ ├── Xcode5Example.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── Xcode5Example.xccheckout │ ├── Xcode5Example │ ├── Base.lproj │ │ ├── Main_iPad.storyboard │ │ └── Main_iPhone.storyboard │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ └── Contents.json │ │ ├── buttons.imageset │ │ │ ├── Contents.json │ │ │ ├── buttons.png │ │ │ └── buttons@2x.png │ │ ├── calendar.imageset │ │ │ ├── Contents.json │ │ │ ├── calendar.png │ │ │ └── calendar@2x.png │ │ └── map.imageset │ │ │ ├── Contents.json │ │ │ ├── map.png │ │ │ └── map@2x.png │ ├── Launch Screen.xib │ ├── MZAppDelegate.h │ ├── MZAppDelegate.m │ ├── MZCustomTransition.h │ ├── MZCustomTransition.m │ ├── MZModalViewController.h │ ├── MZModalViewController.m │ ├── MZNavigationViewController.h │ ├── MZNavigationViewController.m │ ├── MZTableViewController.h │ ├── MZTableViewController.m │ ├── MZViewController.h │ ├── MZViewController.m │ ├── Xcode5Example-Info.plist │ ├── Xcode5Example-Prefix.pch │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m │ └── Xcode5ExampleTests │ ├── Xcode5ExampleTests-Info.plist │ ├── Xcode5ExampleTests.m │ └── en.lproj │ └── InfoPlist.strings ├── LICENSE ├── MZFormSheetController+SVProgressHUD ├── MZFormSheetController+SVProgressHUD.h └── MZFormSheetController+SVProgressHUD.m ├── MZFormSheetController.podspec ├── MZFormSheetController ├── MZFormSheetBackgroundWindow.h ├── MZFormSheetBackgroundWindow.m ├── MZFormSheetBackgroundWindowViewController.h ├── MZFormSheetBackgroundWindowViewController.m ├── MZFormSheetController.h ├── MZFormSheetController.m ├── MZFormSheetSegue.h ├── MZFormSheetSegue.m ├── MZFormSheetTransition.h ├── MZFormSheetTransition.m ├── MZMacro.h ├── UIImage+Additional.h ├── UIImage+Additional.m ├── UIViewController+TargetViewController.h └── UIViewController+TargetViewController.m ├── README.md └── Screens ├── animation.gif ├── animation1.gif ├── screen1.png ├── screen2.png └── screen3.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | DerivedData 17 | .idea/ 18 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "7.0" 2 | pod 'MZAppearance' -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MZAppearance (1.1.5) 3 | 4 | DEPENDENCIES: 5 | - MZAppearance 6 | 7 | SPEC CHECKSUMS: 8 | MZAppearance: 6e9dc64e42074c0a19812a327f590746c3283bab 9 | 10 | COCOAPODS: 0.37.2 11 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Headers/Private/MZAppearance/MZAppearance.h: -------------------------------------------------------------------------------- 1 | ../../../MZAppearance/MZAppearance/MZAppearance.h -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Headers/Private/MZAppearance/NSInvocation+Copy.h: -------------------------------------------------------------------------------- 1 | ../../../MZAppearance/MZAppearance/NSInvocation+Copy.h -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Headers/Public/MZAppearance/MZAppearance.h: -------------------------------------------------------------------------------- 1 | ../../../MZAppearance/MZAppearance/MZAppearance.h -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Headers/Public/MZAppearance/NSInvocation+Copy.h: -------------------------------------------------------------------------------- 1 | ../../../MZAppearance/MZAppearance/NSInvocation+Copy.h -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/MZAppearance/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Michał Zaborowski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/MZAppearance/MZAppearance/MZAppearance.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZApperance.h 3 | // MZAppearance 4 | // 5 | // Created by Michał Zaborowski on 17.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | 28 | #define MZ_APPEARANCE_SELECTOR UI_APPEARANCE_SELECTOR 29 | 30 | @protocol MZAppearance 31 | 32 | /** 33 | To customize the appearance of all instances of a class, send the relevant appearance modification messages to the appearance proxy for the class. 34 | */ 35 | + (instancetype)appearance; 36 | @end 37 | 38 | @interface MZAppearance : NSObject 39 | 40 | /** 41 | Applies the appearance of all instances to the object. 42 | */ 43 | - (void)applyInvocationTo:(id)target; 44 | 45 | /** 46 | Applies the appearance of all instances to the object starting from the superclass 47 | */ 48 | - (void)applyInvocationRecursivelyTo:(id)target upToSuperClass:(Class)superClass; 49 | 50 | /** 51 | Returns appearance for class 52 | */ 53 | + (id)appearanceForClass:(Class)aClass; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/MZAppearance/MZAppearance/MZAppearance.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZApperance.m 3 | // MZAppearance 4 | // 5 | // Created by Michał Zaborowski on 17.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "MZAppearance.h" 27 | 28 | static NSMutableDictionary *instanceOfClassesDictionary = nil; 29 | 30 | @interface MZAppearance () 31 | @property (strong, nonatomic) Class mainClass; 32 | @property (strong, nonatomic) NSMutableArray *invocations; 33 | @end 34 | 35 | @implementation MZAppearance 36 | 37 | - (id)initWithClass:(Class)thisClass 38 | { 39 | _mainClass = thisClass; 40 | _invocations = [NSMutableArray array]; 41 | 42 | return self; 43 | } 44 | 45 | - (void)applyInvocationTo:(id)target 46 | { 47 | for (NSInvocation *invocation in self.invocations) { 48 | 49 | // Create a new copy of the stored invocation, 50 | // otherwise setting the new target, this will never be released 51 | // because the invocation in the array is still alive after the call 52 | 53 | NSInvocation *targetInvocation = [invocation copy]; 54 | [targetInvocation setTarget:target]; 55 | [targetInvocation invoke]; 56 | targetInvocation = nil; 57 | } 58 | } 59 | 60 | - (void)applyInvocationRecursivelyTo:(id)target upToSuperClass:(Class)superClass 61 | { 62 | NSMutableArray *classes = [NSMutableArray array]; 63 | 64 | // We now need to first set the properties of the superclass 65 | for (Class class = [target class]; 66 | [class isSubclassOfClass:superClass] || class == superClass; 67 | class = [class superclass]) { 68 | [classes addObject:class]; 69 | } 70 | 71 | NSEnumerator *reverseClasses = [classes reverseObjectEnumerator]; 72 | 73 | for (Class class in reverseClasses) { 74 | [[MZAppearance appearanceForClass:class] applyInvocationTo:target]; 75 | } 76 | } 77 | 78 | + (id)appearanceForClass:(Class)aClass 79 | { 80 | static dispatch_once_t onceToken; 81 | 82 | dispatch_once(&onceToken, ^{ 83 | instanceOfClassesDictionary = [[NSMutableDictionary alloc] init]; 84 | }); 85 | 86 | if (![instanceOfClassesDictionary objectForKey:NSStringFromClass(aClass)]) 87 | { 88 | id appearance = [[self alloc] initWithClass:aClass]; 89 | [instanceOfClassesDictionary setObject:appearance forKey:NSStringFromClass(aClass)]; 90 | return appearance; 91 | } 92 | else { 93 | return [instanceOfClassesDictionary objectForKey:NSStringFromClass(aClass)]; 94 | } 95 | 96 | } 97 | 98 | - (void)forwardInvocation:(NSInvocation *)anInvocation; 99 | { 100 | [anInvocation setTarget:nil]; 101 | [anInvocation retainArguments]; 102 | 103 | [self.invocations addObject:anInvocation]; 104 | } 105 | 106 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector 107 | { 108 | return [self.mainClass instanceMethodSignatureForSelector:aSelector]; 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/MZAppearance/MZAppearance/NSInvocation+Copy.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSInvocation+Copy.h 3 | // MZFormSheetControllerExample 4 | // 5 | // Created by Michał Zaborowski on 17.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | 28 | @interface NSInvocation (Copy) 29 | 30 | - (id)copy; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/MZAppearance/MZAppearance/NSInvocation+Copy.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSInvocation+Copy.m 3 | // MZFormSheetControllerExample 4 | // 5 | // Created by Michał Zaborowski on 17.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "NSInvocation+Copy.h" 27 | 28 | @interface NSString (Encoding) 29 | 30 | - (BOOL)mz_isFirstCharacterEqual:(NSString *)string; 31 | - (BOOL)mz_isFirstCharacterCaseInsensitiveEqual:(NSString *)string; 32 | - (NSString *)mz_stringByRemovingMethodEnodingQualifiers; 33 | 34 | @end 35 | 36 | @implementation NSString (Encoding) 37 | 38 | - (BOOL)mz_isFirstCharacterEqual:(NSString *)string 39 | { 40 | if (self.length < 1 || string.length < 1) { 41 | return NO; 42 | } 43 | return [[self substringToIndex:1] isEqualToString:[string substringToIndex:1]]; 44 | } 45 | 46 | - (BOOL)mz_isFirstCharacterCaseInsensitiveEqual:(NSString *)string 47 | { 48 | if (self.length < 1 || string.length < 1) { 49 | return NO; 50 | } 51 | return [[self substringToIndex:1] caseInsensitiveCompare:[string substringToIndex:1]] == NSOrderedSame; 52 | } 53 | 54 | - (NSString *)mz_stringByRemovingMethodEnodingQualifiers 55 | { 56 | if ([self mz_isFirstCharacterCaseInsensitiveEqual:@"r"] || 57 | [self mz_isFirstCharacterCaseInsensitiveEqual:@"n"] || 58 | [self mz_isFirstCharacterCaseInsensitiveEqual:@"o"] || 59 | [self mz_isFirstCharacterEqual:@"V"]) { 60 | return [self substringFromIndex:1]; 61 | } else { 62 | return self; 63 | } 64 | } 65 | 66 | @end 67 | 68 | BOOL mz_areObjCTypesEqual(NSString *argmuentType, const char *encodingType) { 69 | 70 | NSString *encoding = [NSString stringWithUTF8String:encodingType]; 71 | return [[argmuentType mz_stringByRemovingMethodEnodingQualifiers] isEqualToString:[encoding mz_stringByRemovingMethodEnodingQualifiers]]; 72 | } 73 | 74 | @implementation NSInvocation (Copy) 75 | 76 | // http://stackoverflow.com/questions/15732885/uiappearance-proxy-for-custom-objects 77 | 78 | - (id)copy 79 | { 80 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:self.methodSignature]; 81 | NSUInteger numberOfArguments = [[self methodSignature] numberOfArguments]; 82 | 83 | [invocation setTarget:self.target]; 84 | [invocation setSelector:self.selector]; 85 | 86 | if (numberOfArguments > 2) { 87 | for (int i = 0; i < (numberOfArguments - 2); i++) { 88 | NSInteger index = i+2; 89 | 90 | NSString *argumentType = [NSString stringWithUTF8String:[self.methodSignature getArgumentTypeAtIndex:index]]; 91 | 92 | if (mz_areObjCTypesEqual(argumentType, @encode(char))) { 93 | char arg; 94 | [self getArgument:&arg atIndex:index]; 95 | [invocation setArgument:&arg atIndex:index]; 96 | } else if (mz_areObjCTypesEqual(argumentType, @encode(unsigned char))) { 97 | unsigned char arg; 98 | [self getArgument:&arg atIndex:index]; 99 | [invocation setArgument:&arg atIndex:index]; 100 | } else if (mz_areObjCTypesEqual(argumentType, @encode(bool))) { 101 | bool arg; 102 | [self getArgument:&arg atIndex:index]; 103 | [invocation setArgument:&arg atIndex:index]; 104 | } else if (mz_areObjCTypesEqual(argumentType, @encode(short))) { 105 | short arg; 106 | [self getArgument:&arg atIndex:index]; 107 | [invocation setArgument:&arg atIndex:index]; 108 | } else if (mz_areObjCTypesEqual(argumentType, @encode(unsigned short))) { 109 | unsigned short arg; 110 | [self getArgument:&arg atIndex:index]; 111 | [invocation setArgument:&arg atIndex:index]; 112 | } else if (mz_areObjCTypesEqual(argumentType, @encode(int))) { 113 | int arg; 114 | [self getArgument:&arg atIndex:index]; 115 | [invocation setArgument:&arg atIndex:index]; 116 | } else if (mz_areObjCTypesEqual(argumentType, @encode(unsigned int))) { 117 | unsigned int arg; 118 | [self getArgument:&arg atIndex:index]; 119 | [invocation setArgument:&arg atIndex:index]; 120 | } else if (mz_areObjCTypesEqual(argumentType, @encode(long))) { 121 | long arg; 122 | [self getArgument:&arg atIndex:index]; 123 | [invocation setArgument:&arg atIndex:index]; 124 | } else if (mz_areObjCTypesEqual(argumentType, @encode(unsigned long))) { 125 | unsigned long arg; 126 | [self getArgument:&arg atIndex:index]; 127 | [invocation setArgument:&arg atIndex:index]; 128 | } else if (mz_areObjCTypesEqual(argumentType, @encode(long long))) { 129 | long long arg; 130 | [self getArgument:&arg atIndex:index]; 131 | [invocation setArgument:&arg atIndex:index]; 132 | } else if (mz_areObjCTypesEqual(argumentType, @encode(unsigned long long))) { 133 | unsigned long long arg; 134 | [self getArgument:&arg atIndex:index]; 135 | [invocation setArgument:&arg atIndex:index]; 136 | } else if (mz_areObjCTypesEqual(argumentType, @encode(float))) { 137 | float arg; 138 | [self getArgument:&arg atIndex:index]; 139 | [invocation setArgument:&arg atIndex:index]; 140 | } else if (mz_areObjCTypesEqual(argumentType, @encode(double))) { 141 | double arg; 142 | [self getArgument:&arg atIndex:index]; 143 | [invocation setArgument:&arg atIndex:index]; 144 | } else if (mz_areObjCTypesEqual(argumentType, @encode(id))) { 145 | char buffer[sizeof(intmax_t)]; 146 | [self getArgument:(void *)&buffer atIndex:i + 2]; 147 | [invocation setArgument:(void *)&buffer atIndex:i + 2]; 148 | } else if (mz_areObjCTypesEqual(argumentType, @encode(SEL))) { 149 | SEL arg; 150 | [self getArgument:&arg atIndex:index]; 151 | [invocation setArgument:&arg atIndex:index]; 152 | } else if (mz_areObjCTypesEqual(argumentType, @encode(Class))) { 153 | Class arg; 154 | [self getArgument:&arg atIndex:index]; 155 | [invocation setArgument:&arg atIndex:index]; 156 | } else if (mz_areObjCTypesEqual(argumentType, @encode(char *))) { 157 | char *arg; 158 | [self getArgument:&arg atIndex:index]; 159 | [invocation setArgument:&arg atIndex:index]; 160 | } else if (mz_areObjCTypesEqual(argumentType, @encode(NSRange))) { 161 | NSRange arg; 162 | [self getArgument:&arg atIndex:index]; 163 | [invocation setArgument:&arg atIndex:index]; 164 | } else if (mz_areObjCTypesEqual(argumentType, @encode(CGPoint))) { 165 | CGPoint arg; 166 | [self getArgument:&arg atIndex:index]; 167 | [invocation setArgument:&arg atIndex:index]; 168 | } else if (mz_areObjCTypesEqual(argumentType, @encode(CGSize))) { 169 | CGSize arg; 170 | [self getArgument:&arg atIndex:index]; 171 | [invocation setArgument:&arg atIndex:index]; 172 | } else if (mz_areObjCTypesEqual(argumentType, @encode(CGColorRef))) { 173 | CGColorRef arg; 174 | [self getArgument:&arg atIndex:index]; 175 | [invocation setArgument:&arg atIndex:index]; 176 | } else if (mz_areObjCTypesEqual(argumentType, @encode(CGRect))) { 177 | CGRect arg; 178 | [self getArgument:&arg atIndex:index]; 179 | [invocation setArgument:&arg atIndex:index]; 180 | } else if ([argumentType mz_isFirstCharacterEqual:@"^"]) { 181 | // generic pointer, including function pointers 182 | 183 | void *arg; 184 | [self getArgument:&arg atIndex:index]; 185 | [invocation setArgument:&arg atIndex:index]; 186 | } else if ([argumentType mz_isFirstCharacterEqual:@"@"]) { 187 | // most likely a block, handle like a function pointer 188 | 189 | id arg; 190 | [self getArgument:&arg atIndex:index]; 191 | [invocation setArgument:&arg atIndex:index]; 192 | } else { 193 | 194 | const char *argumentType = [self.methodSignature getArgumentTypeAtIndex:index]; 195 | 196 | NSUInteger argumentLength; 197 | NSGetSizeAndAlignment(argumentType, &argumentLength, NULL); 198 | 199 | void *buffer = malloc(argumentLength); 200 | 201 | if (buffer) { 202 | [self getArgument:buffer atIndex:index]; 203 | [invocation setArgument:buffer atIndex:index]; 204 | 205 | free(buffer); 206 | } 207 | } 208 | 209 | } 210 | } 211 | 212 | return invocation; 213 | } 214 | 215 | @end 216 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/MZAppearance/README.md: -------------------------------------------------------------------------------- 1 | MZAppearance 2 | ============ 3 | 4 | UIAppearance proxy for custom objects 5 | 6 | ## How To Use 7 | 8 | All you need is mark a method that participates in the appearance proxy API using MZ_APPEARANCE_SELECTOR. 9 | Implement protocol method + (id)appearance, and call applyInvocationTo inside your init or viewDidLoad object method. 10 | 11 | ``` objective-c 12 | @interface MZViewController : UIViewController 13 | 14 | @property (nonatomic,strong) UIColor *customColor MZ_APPEARANCE_SELECTOR; 15 | @property (nonatomic,assign) CGFloat customFloat MZ_APPEARANCE_SELECTOR; 16 | 17 | + (id)appearance; 18 | 19 | @end 20 | ``` 21 | 22 | ``` objective-c 23 | + (id)appearance 24 | { 25 | return [MZAppearance appearanceForClass:[self class]]; 26 | } 27 | 28 | - (void)viewDidLoad 29 | { 30 | [super viewDidLoad]; 31 | 32 | [[[self class] appearance] applyInvocationTo:self]; 33 | 34 | NSLog(@"custom color: %@",self.customColor); 35 | NSLog(@"custom float: %f",self.customFloat); 36 | } 37 | ``` 38 | 39 | ## How to setup appearance variable 40 | 41 | ``` objective-c 42 | [[MZViewController appearance] setCustomColor:[UIColor blackColor]]; 43 | [[MZViewController appearance] setCustomFloat:6.0]; 44 | ``` 45 | 46 | Console result will be 47 | 48 | ``` objective-c 49 | 2013-08-17 19:59:38.546 MZAppearance[3374:c07] custom color: UIDeviceWhiteColorSpace 0 1 50 | 2013-08-17 19:59:38.547 MZAppearance[3374:c07] custom float: 6.000000 51 | ``` 52 | 53 | 54 | 55 | 56 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/m1entus/mzappearance/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 57 | 58 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MZAppearance (1.1.5) 3 | 4 | DEPENDENCIES: 5 | - MZAppearance 6 | 7 | SPEC CHECKSUMS: 8 | MZAppearance: 6e9dc64e42074c0a19812a327f590746c3283bab 9 | 10 | COCOAPODS: 0.37.2 11 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0FD2E3AFAF6ED5FDAAAF8726 /* Pods-MZAppearance-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A275F959C8E72A0F38208E3 /* Pods-MZAppearance-dummy.m */; }; 11 | 243828AC64D91125D13BDF9F /* Pods-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B1AA34E13EDF6A02850F4A77 /* Pods-dummy.m */; }; 12 | 2BBF46F8156737CA0389A242 /* MZAppearance.m in Sources */ = {isa = PBXBuildFile; fileRef = AA9F78B32E04DDD0D95FA2E5 /* MZAppearance.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 13 | 3DBCB9373A597242A13ED48E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42F14ECF2168EDC8F8DD3B2A /* QuartzCore.framework */; }; 14 | 3E0EDBD3E6D2CDCEE6CBD80A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DAF28505B8E2D60700ACC38 /* Foundation.framework */; }; 15 | 7637AF0FA052D6EF7A91F8D7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DAF28505B8E2D60700ACC38 /* Foundation.framework */; }; 16 | 9F808393E001E8F402C40F5A /* NSInvocation+Copy.h in Headers */ = {isa = PBXBuildFile; fileRef = 038A29C47377E3810846497F /* NSInvocation+Copy.h */; }; 17 | B45A01EA7FAC7ADE68862E1E /* MZAppearance.h in Headers */ = {isa = PBXBuildFile; fileRef = D4BFC62C3FC47FC0BA59130A /* MZAppearance.h */; }; 18 | BD6A7C3293FD1F2281D82C37 /* NSInvocation+Copy.m in Sources */ = {isa = PBXBuildFile; fileRef = 79E33F6850F2EE090C1AEEAD /* NSInvocation+Copy.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0"; }; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 065FCCFF5578227E33E6C21A /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 3C571768E7111FA62D2508C9 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = F8A6AC3AB385FA8AB7EEABFC; 27 | remoteInfo = "Pods-MZAppearance"; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 038A29C47377E3810846497F /* NSInvocation+Copy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSInvocation+Copy.h"; path = "MZAppearance/NSInvocation+Copy.h"; sourceTree = ""; }; 33 | 063FFF1353482F0CFB84A4D2 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 1DAF28505B8E2D60700ACC38 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 35 | 2F77CD7EA8C10DF9F2AF7D0E /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.debug.xcconfig; sourceTree = ""; }; 36 | 42F14ECF2168EDC8F8DD3B2A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; 37 | 673CA80C6F919AAEC214A4F9 /* Pods-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-acknowledgements.markdown"; sourceTree = ""; }; 38 | 6A275F959C8E72A0F38208E3 /* Pods-MZAppearance-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-MZAppearance-dummy.m"; sourceTree = ""; }; 39 | 79E33F6850F2EE090C1AEEAD /* NSInvocation+Copy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSInvocation+Copy.m"; path = "MZAppearance/NSInvocation+Copy.m"; sourceTree = ""; }; 40 | A49D5061CCC2FD0B923FB0B7 /* Pods-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-resources.sh"; sourceTree = ""; }; 41 | AA9F78B32E04DDD0D95FA2E5 /* MZAppearance.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MZAppearance.m; path = MZAppearance/MZAppearance.m; sourceTree = ""; }; 42 | B1AA34E13EDF6A02850F4A77 /* Pods-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-dummy.m"; sourceTree = ""; }; 43 | B43476E785070171131D1E10 /* Pods-MZAppearance-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MZAppearance-Private.xcconfig"; sourceTree = ""; }; 44 | B73C251A86E8AD0F71FB7764 /* Pods-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-acknowledgements.plist"; sourceTree = ""; }; 45 | BF1538E3AF9853BB42A6449E /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 46 | CABC6027A599E70F67BD8FF3 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.release.xcconfig; sourceTree = ""; }; 47 | D4BFC62C3FC47FC0BA59130A /* MZAppearance.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MZAppearance.h; path = MZAppearance/MZAppearance.h; sourceTree = ""; }; 48 | D7F7636316F7259AC105C905 /* Pods-environment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-environment.h"; sourceTree = ""; }; 49 | DA105846C98AB7391FCA8CE1 /* Pods-MZAppearance-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-MZAppearance-prefix.pch"; sourceTree = ""; }; 50 | E3BC411415C84193AD07A734 /* Pods-MZAppearance.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MZAppearance.xcconfig"; sourceTree = ""; }; 51 | FB0C98C29553ED4CD1F9C0BE /* libPods-MZAppearance.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MZAppearance.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 94B1888DEDD8C75769642914 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 7637AF0FA052D6EF7A91F8D7 /* Foundation.framework in Frameworks */, 60 | 3DBCB9373A597242A13ED48E /* QuartzCore.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | A8F1FD55B9C3599A73CBE767 /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | 3E0EDBD3E6D2CDCEE6CBD80A /* Foundation.framework in Frameworks */, 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | /* End PBXFrameworksBuildPhase section */ 73 | 74 | /* Begin PBXGroup section */ 75 | 2F4902971153C407B1883137 /* iOS */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 1DAF28505B8E2D60700ACC38 /* Foundation.framework */, 79 | 42F14ECF2168EDC8F8DD3B2A /* QuartzCore.framework */, 80 | ); 81 | name = iOS; 82 | sourceTree = ""; 83 | }; 84 | 37540089BF0D9606B9CAAF39 /* Pods */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 673CA80C6F919AAEC214A4F9 /* Pods-acknowledgements.markdown */, 88 | B73C251A86E8AD0F71FB7764 /* Pods-acknowledgements.plist */, 89 | B1AA34E13EDF6A02850F4A77 /* Pods-dummy.m */, 90 | D7F7636316F7259AC105C905 /* Pods-environment.h */, 91 | A49D5061CCC2FD0B923FB0B7 /* Pods-resources.sh */, 92 | 2F77CD7EA8C10DF9F2AF7D0E /* Pods.debug.xcconfig */, 93 | CABC6027A599E70F67BD8FF3 /* Pods.release.xcconfig */, 94 | ); 95 | name = Pods; 96 | path = "Target Support Files/Pods"; 97 | sourceTree = ""; 98 | }; 99 | 3A107F58F1FB552FD62DA3B7 /* Targets Support Files */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 37540089BF0D9606B9CAAF39 /* Pods */, 103 | ); 104 | name = "Targets Support Files"; 105 | sourceTree = ""; 106 | }; 107 | 44E12714405AF2C49D97572A /* Pods */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | E4BA1EB4C21EB078A91475C2 /* MZAppearance */, 111 | ); 112 | name = Pods; 113 | sourceTree = ""; 114 | }; 115 | 64974D270810EE8772658BB7 /* Products */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 063FFF1353482F0CFB84A4D2 /* libPods.a */, 119 | FB0C98C29553ED4CD1F9C0BE /* libPods-MZAppearance.a */, 120 | ); 121 | name = Products; 122 | sourceTree = ""; 123 | }; 124 | D11AF65D99BDB37106F45189 /* Support Files */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | E3BC411415C84193AD07A734 /* Pods-MZAppearance.xcconfig */, 128 | B43476E785070171131D1E10 /* Pods-MZAppearance-Private.xcconfig */, 129 | 6A275F959C8E72A0F38208E3 /* Pods-MZAppearance-dummy.m */, 130 | DA105846C98AB7391FCA8CE1 /* Pods-MZAppearance-prefix.pch */, 131 | ); 132 | name = "Support Files"; 133 | path = "../Target Support Files/Pods-MZAppearance"; 134 | sourceTree = ""; 135 | }; 136 | E4BA1EB4C21EB078A91475C2 /* MZAppearance */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | D4BFC62C3FC47FC0BA59130A /* MZAppearance.h */, 140 | AA9F78B32E04DDD0D95FA2E5 /* MZAppearance.m */, 141 | 038A29C47377E3810846497F /* NSInvocation+Copy.h */, 142 | 79E33F6850F2EE090C1AEEAD /* NSInvocation+Copy.m */, 143 | D11AF65D99BDB37106F45189 /* Support Files */, 144 | ); 145 | path = MZAppearance; 146 | sourceTree = ""; 147 | }; 148 | EFE0AC18CB2B7D3888150328 = { 149 | isa = PBXGroup; 150 | children = ( 151 | BF1538E3AF9853BB42A6449E /* Podfile */, 152 | FB04D40AB5C7C5540240B958 /* Frameworks */, 153 | 44E12714405AF2C49D97572A /* Pods */, 154 | 64974D270810EE8772658BB7 /* Products */, 155 | 3A107F58F1FB552FD62DA3B7 /* Targets Support Files */, 156 | ); 157 | sourceTree = ""; 158 | }; 159 | FB04D40AB5C7C5540240B958 /* Frameworks */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 2F4902971153C407B1883137 /* iOS */, 163 | ); 164 | name = Frameworks; 165 | sourceTree = ""; 166 | }; 167 | /* End PBXGroup section */ 168 | 169 | /* Begin PBXHeadersBuildPhase section */ 170 | B569E27DDDC0FDA06A260527 /* Headers */ = { 171 | isa = PBXHeadersBuildPhase; 172 | buildActionMask = 2147483647; 173 | files = ( 174 | B45A01EA7FAC7ADE68862E1E /* MZAppearance.h in Headers */, 175 | 9F808393E001E8F402C40F5A /* NSInvocation+Copy.h in Headers */, 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXHeadersBuildPhase section */ 180 | 181 | /* Begin PBXNativeTarget section */ 182 | 2D153F79C2F913097822638A /* Pods */ = { 183 | isa = PBXNativeTarget; 184 | buildConfigurationList = 27C8000F0FEB5598D119E738 /* Build configuration list for PBXNativeTarget "Pods" */; 185 | buildPhases = ( 186 | C5EF8D15DEF287360364F10B /* Sources */, 187 | A8F1FD55B9C3599A73CBE767 /* Frameworks */, 188 | ); 189 | buildRules = ( 190 | ); 191 | dependencies = ( 192 | A3E3CA7CB5E8D4B981D678BD /* PBXTargetDependency */, 193 | ); 194 | name = Pods; 195 | productName = Pods; 196 | productReference = 063FFF1353482F0CFB84A4D2 /* libPods.a */; 197 | productType = "com.apple.product-type.library.static"; 198 | }; 199 | F8A6AC3AB385FA8AB7EEABFC /* Pods-MZAppearance */ = { 200 | isa = PBXNativeTarget; 201 | buildConfigurationList = 823A611FC6F730D3C1E0B4B0 /* Build configuration list for PBXNativeTarget "Pods-MZAppearance" */; 202 | buildPhases = ( 203 | E2A3A504D171B2D98DF45093 /* Sources */, 204 | 94B1888DEDD8C75769642914 /* Frameworks */, 205 | B569E27DDDC0FDA06A260527 /* Headers */, 206 | ); 207 | buildRules = ( 208 | ); 209 | dependencies = ( 210 | ); 211 | name = "Pods-MZAppearance"; 212 | productName = "Pods-MZAppearance"; 213 | productReference = FB0C98C29553ED4CD1F9C0BE /* libPods-MZAppearance.a */; 214 | productType = "com.apple.product-type.library.static"; 215 | }; 216 | /* End PBXNativeTarget section */ 217 | 218 | /* Begin PBXProject section */ 219 | 3C571768E7111FA62D2508C9 /* Project object */ = { 220 | isa = PBXProject; 221 | attributes = { 222 | LastUpgradeCheck = 0640; 223 | }; 224 | buildConfigurationList = 524D3784551F303572ED351D /* Build configuration list for PBXProject "Pods" */; 225 | compatibilityVersion = "Xcode 3.2"; 226 | developmentRegion = English; 227 | hasScannedForEncodings = 0; 228 | knownRegions = ( 229 | en, 230 | ); 231 | mainGroup = EFE0AC18CB2B7D3888150328; 232 | productRefGroup = 64974D270810EE8772658BB7 /* Products */; 233 | projectDirPath = ""; 234 | projectRoot = ""; 235 | targets = ( 236 | 2D153F79C2F913097822638A /* Pods */, 237 | F8A6AC3AB385FA8AB7EEABFC /* Pods-MZAppearance */, 238 | ); 239 | }; 240 | /* End PBXProject section */ 241 | 242 | /* Begin PBXSourcesBuildPhase section */ 243 | C5EF8D15DEF287360364F10B /* Sources */ = { 244 | isa = PBXSourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 243828AC64D91125D13BDF9F /* Pods-dummy.m in Sources */, 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | }; 251 | E2A3A504D171B2D98DF45093 /* Sources */ = { 252 | isa = PBXSourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | 2BBF46F8156737CA0389A242 /* MZAppearance.m in Sources */, 256 | BD6A7C3293FD1F2281D82C37 /* NSInvocation+Copy.m in Sources */, 257 | 0FD2E3AFAF6ED5FDAAAF8726 /* Pods-MZAppearance-dummy.m in Sources */, 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | /* End PBXSourcesBuildPhase section */ 262 | 263 | /* Begin PBXTargetDependency section */ 264 | A3E3CA7CB5E8D4B981D678BD /* PBXTargetDependency */ = { 265 | isa = PBXTargetDependency; 266 | name = "Pods-MZAppearance"; 267 | target = F8A6AC3AB385FA8AB7EEABFC /* Pods-MZAppearance */; 268 | targetProxy = 065FCCFF5578227E33E6C21A /* PBXContainerItemProxy */; 269 | }; 270 | /* End PBXTargetDependency section */ 271 | 272 | /* Begin XCBuildConfiguration section */ 273 | 1B963165A180284E88764EE4 /* Debug */ = { 274 | isa = XCBuildConfiguration; 275 | baseConfigurationReference = B43476E785070171131D1E10 /* Pods-MZAppearance-Private.xcconfig */; 276 | buildSettings = { 277 | ENABLE_STRICT_OBJC_MSGSEND = YES; 278 | GCC_PREFIX_HEADER = "Target Support Files/Pods-MZAppearance/Pods-MZAppearance-prefix.pch"; 279 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 280 | MTL_ENABLE_DEBUG_INFO = YES; 281 | OTHER_LDFLAGS = ""; 282 | OTHER_LIBTOOLFLAGS = ""; 283 | PRODUCT_NAME = "$(TARGET_NAME)"; 284 | SDKROOT = iphoneos; 285 | SKIP_INSTALL = YES; 286 | }; 287 | name = Debug; 288 | }; 289 | 228E7F1CF1D05DE2A73AB597 /* Debug */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | ALWAYS_SEARCH_USER_PATHS = NO; 293 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 294 | CLANG_CXX_LIBRARY = "libc++"; 295 | CLANG_ENABLE_MODULES = YES; 296 | CLANG_ENABLE_OBJC_ARC = YES; 297 | CLANG_WARN_BOOL_CONVERSION = YES; 298 | CLANG_WARN_CONSTANT_CONVERSION = YES; 299 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 300 | CLANG_WARN_EMPTY_BODY = YES; 301 | CLANG_WARN_ENUM_CONVERSION = YES; 302 | CLANG_WARN_INT_CONVERSION = YES; 303 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 304 | CLANG_WARN_UNREACHABLE_CODE = YES; 305 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 306 | COPY_PHASE_STRIP = NO; 307 | GCC_C_LANGUAGE_STANDARD = gnu99; 308 | GCC_DYNAMIC_NO_PIC = NO; 309 | GCC_OPTIMIZATION_LEVEL = 0; 310 | GCC_PREPROCESSOR_DEFINITIONS = ( 311 | "DEBUG=1", 312 | "$(inherited)", 313 | ); 314 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 315 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 316 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 317 | GCC_WARN_UNDECLARED_SELECTOR = YES; 318 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 319 | GCC_WARN_UNUSED_FUNCTION = YES; 320 | GCC_WARN_UNUSED_VARIABLE = YES; 321 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 322 | ONLY_ACTIVE_ARCH = YES; 323 | STRIP_INSTALLED_PRODUCT = NO; 324 | SYMROOT = "${SRCROOT}/../build"; 325 | }; 326 | name = Debug; 327 | }; 328 | 9D261E26F5BE912579A17331 /* Release */ = { 329 | isa = XCBuildConfiguration; 330 | baseConfigurationReference = B43476E785070171131D1E10 /* Pods-MZAppearance-Private.xcconfig */; 331 | buildSettings = { 332 | ENABLE_STRICT_OBJC_MSGSEND = YES; 333 | GCC_PREFIX_HEADER = "Target Support Files/Pods-MZAppearance/Pods-MZAppearance-prefix.pch"; 334 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 335 | MTL_ENABLE_DEBUG_INFO = NO; 336 | OTHER_LDFLAGS = ""; 337 | OTHER_LIBTOOLFLAGS = ""; 338 | PRODUCT_NAME = "$(TARGET_NAME)"; 339 | SDKROOT = iphoneos; 340 | SKIP_INSTALL = YES; 341 | }; 342 | name = Release; 343 | }; 344 | BBBA7FD7407D5955972DE1D2 /* Debug */ = { 345 | isa = XCBuildConfiguration; 346 | baseConfigurationReference = 2F77CD7EA8C10DF9F2AF7D0E /* Pods.debug.xcconfig */; 347 | buildSettings = { 348 | ENABLE_STRICT_OBJC_MSGSEND = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 350 | MTL_ENABLE_DEBUG_INFO = YES; 351 | OTHER_LDFLAGS = ""; 352 | OTHER_LIBTOOLFLAGS = ""; 353 | PODS_ROOT = "$(SRCROOT)"; 354 | PRODUCT_NAME = "$(TARGET_NAME)"; 355 | SDKROOT = iphoneos; 356 | SKIP_INSTALL = YES; 357 | }; 358 | name = Debug; 359 | }; 360 | DB30AA47D3584A48A9D66DAC /* Release */ = { 361 | isa = XCBuildConfiguration; 362 | buildSettings = { 363 | ALWAYS_SEARCH_USER_PATHS = NO; 364 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 365 | CLANG_CXX_LIBRARY = "libc++"; 366 | CLANG_ENABLE_MODULES = YES; 367 | CLANG_ENABLE_OBJC_ARC = YES; 368 | CLANG_WARN_BOOL_CONVERSION = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 371 | CLANG_WARN_EMPTY_BODY = YES; 372 | CLANG_WARN_ENUM_CONVERSION = YES; 373 | CLANG_WARN_INT_CONVERSION = YES; 374 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 375 | CLANG_WARN_UNREACHABLE_CODE = YES; 376 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 377 | COPY_PHASE_STRIP = YES; 378 | ENABLE_NS_ASSERTIONS = NO; 379 | GCC_C_LANGUAGE_STANDARD = gnu99; 380 | GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1"; 381 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 382 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 383 | GCC_WARN_UNDECLARED_SELECTOR = YES; 384 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 385 | GCC_WARN_UNUSED_FUNCTION = YES; 386 | GCC_WARN_UNUSED_VARIABLE = YES; 387 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 388 | STRIP_INSTALLED_PRODUCT = NO; 389 | SYMROOT = "${SRCROOT}/../build"; 390 | VALIDATE_PRODUCT = YES; 391 | }; 392 | name = Release; 393 | }; 394 | FBBA7A931F3D614698129568 /* Release */ = { 395 | isa = XCBuildConfiguration; 396 | baseConfigurationReference = CABC6027A599E70F67BD8FF3 /* Pods.release.xcconfig */; 397 | buildSettings = { 398 | ENABLE_STRICT_OBJC_MSGSEND = YES; 399 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 400 | MTL_ENABLE_DEBUG_INFO = NO; 401 | OTHER_LDFLAGS = ""; 402 | OTHER_LIBTOOLFLAGS = ""; 403 | PODS_ROOT = "$(SRCROOT)"; 404 | PRODUCT_NAME = "$(TARGET_NAME)"; 405 | SDKROOT = iphoneos; 406 | SKIP_INSTALL = YES; 407 | }; 408 | name = Release; 409 | }; 410 | /* End XCBuildConfiguration section */ 411 | 412 | /* Begin XCConfigurationList section */ 413 | 27C8000F0FEB5598D119E738 /* Build configuration list for PBXNativeTarget "Pods" */ = { 414 | isa = XCConfigurationList; 415 | buildConfigurations = ( 416 | BBBA7FD7407D5955972DE1D2 /* Debug */, 417 | FBBA7A931F3D614698129568 /* Release */, 418 | ); 419 | defaultConfigurationIsVisible = 0; 420 | defaultConfigurationName = Release; 421 | }; 422 | 524D3784551F303572ED351D /* Build configuration list for PBXProject "Pods" */ = { 423 | isa = XCConfigurationList; 424 | buildConfigurations = ( 425 | 228E7F1CF1D05DE2A73AB597 /* Debug */, 426 | DB30AA47D3584A48A9D66DAC /* Release */, 427 | ); 428 | defaultConfigurationIsVisible = 0; 429 | defaultConfigurationName = Release; 430 | }; 431 | 823A611FC6F730D3C1E0B4B0 /* Build configuration list for PBXNativeTarget "Pods-MZAppearance" */ = { 432 | isa = XCConfigurationList; 433 | buildConfigurations = ( 434 | 1B963165A180284E88764EE4 /* Debug */, 435 | 9D261E26F5BE912579A17331 /* Release */, 436 | ); 437 | defaultConfigurationIsVisible = 0; 438 | defaultConfigurationName = Release; 439 | }; 440 | /* End XCConfigurationList section */ 441 | }; 442 | rootObject = 3C571768E7111FA62D2508C9 /* Project object */; 443 | } 444 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods-MZAppearance/Pods-MZAppearance-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-MZAppearance.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/MZAppearance" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MZAppearance" 4 | OTHER_LDFLAGS = ${PODS_MZAPPEARANCE_OTHER_LDFLAGS} -ObjC 5 | PODS_ROOT = ${SRCROOT} 6 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods-MZAppearance/Pods-MZAppearance-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_MZAppearance : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_MZAppearance 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods-MZAppearance/Pods-MZAppearance-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-environment.h" 6 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods-MZAppearance/Pods-MZAppearance.xcconfig: -------------------------------------------------------------------------------- 1 | PODS_MZAPPEARANCE_OTHER_LDFLAGS = -framework "QuartzCore" -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## MZAppearance 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2013 Michał Zaborowski 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy of 11 | this software and associated documentation files (the "Software"), to deal in 12 | the Software without restriction, including without limitation the rights to 13 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 14 | the Software, and to permit persons to whom the Software is furnished to do so, 15 | subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 22 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 23 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 24 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 25 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | Generated by CocoaPods - http://cocoapods.org 28 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/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 | The MIT License (MIT) 18 | 19 | Copyright (c) 2013 Michał Zaborowski 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy of 22 | this software and associated documentation files (the "Software"), to deal in 23 | the Software without restriction, including without limitation the rights to 24 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 25 | the Software, and to permit persons to whom the Software is furnished to do so, 26 | subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 33 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 34 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 35 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 36 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 | 38 | Title 39 | MZAppearance 40 | Type 41 | PSGroupSpecifier 42 | 43 | 44 | FooterText 45 | Generated by CocoaPods - http://cocoapods.org 46 | Title 47 | 48 | Type 49 | PSGroupSpecifier 50 | 51 | 52 | StringsTable 53 | Acknowledgements 54 | Title 55 | Acknowledgements 56 | 57 | 58 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods/Pods-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods : NSObject 3 | @end 4 | @implementation PodsDummy_Pods 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/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 | // MZAppearance 10 | #define COCOAPODS_POD_AVAILABLE_MZAppearance 11 | #define COCOAPODS_VERSION_MAJOR_MZAppearance 1 12 | #define COCOAPODS_VERSION_MINOR_MZAppearance 1 13 | #define COCOAPODS_VERSION_PATCH_MZAppearance 5 14 | 15 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods/Pods-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | realpath() { 12 | DIRECTORY=$(cd "${1%/*}" && pwd) 13 | FILENAME="${1##*/}" 14 | echo "$DIRECTORY/$FILENAME" 15 | } 16 | 17 | install_resource() 18 | { 19 | case $1 in 20 | *.storyboard) 21 | 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}" 22 | 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}" 23 | ;; 24 | *.xib) 25 | 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}" 26 | 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}" 27 | ;; 28 | *.framework) 29 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 30 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 31 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 32 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 33 | ;; 34 | *.xcdatamodel) 35 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 36 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 37 | ;; 38 | *.xcdatamodeld) 39 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 40 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 41 | ;; 42 | *.xcmappingmodel) 43 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 44 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 45 | ;; 46 | *.xcassets) 47 | ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") 48 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 49 | ;; 50 | /*) 51 | echo "$1" 52 | echo "$1" >> "$RESOURCES_TO_COPY" 53 | ;; 54 | *) 55 | echo "${PODS_ROOT}/$1" 56 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 57 | ;; 58 | esac 59 | } 60 | 61 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 62 | if [[ "${ACTION}" == "install" ]]; then 63 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 64 | fi 65 | rm -f "$RESOURCES_TO_COPY" 66 | 67 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 68 | then 69 | case "${TARGETED_DEVICE_FAMILY}" in 70 | 1,2) 71 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 72 | ;; 73 | 1) 74 | TARGET_DEVICE_ARGS="--target-device iphone" 75 | ;; 76 | 2) 77 | TARGET_DEVICE_ARGS="--target-device ipad" 78 | ;; 79 | *) 80 | TARGET_DEVICE_ARGS="--target-device mac" 81 | ;; 82 | esac 83 | 84 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 85 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 86 | while read line; do 87 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 88 | XCASSET_FILES+=("$line") 89 | fi 90 | done <<<"$OTHER_XCASSETS" 91 | 92 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun 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}" 93 | fi 94 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods/Pods.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MZAppearance" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MZAppearance" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"Pods-MZAppearance" -framework "QuartzCore" 5 | OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) 6 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Pods/Target Support Files/Pods/Pods.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MZAppearance" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MZAppearance" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"Pods-MZAppearance" -framework "QuartzCore" 5 | OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) 6 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example.xcodeproj/project.xcworkspace/xcshareddata/Xcode5Example.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | EE7334CA-734A-45A0-B3F9-0BDAD6F03666 9 | IDESourceControlProjectName 10 | Xcode5Example 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 6C955D289CBA1732476159B45995922140378636 14 | https://github.com/m1entus/MZFormSheetController.git 15 | 16 | IDESourceControlProjectPath 17 | Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 6C955D289CBA1732476159B45995922140378636 21 | ../../../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/m1entus/MZFormSheetController.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 6C955D289CBA1732476159B45995922140378636 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 6C955D289CBA1732476159B45995922140378636 36 | IDESourceControlWCCName 37 | MZFormSheetController 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example.xcworkspace/xcshareddata/Xcode5Example.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | B51F9B48-9590-451E-BC23-2A407056639D 9 | IDESourceControlProjectName 10 | Xcode5Example 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 6C955D289CBA1732476159B45995922140378636 14 | https://github.com/m1entus/MZFormSheetController.git 15 | 16 | IDESourceControlProjectPath 17 | Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 6C955D289CBA1732476159B45995922140378636 21 | ../../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/m1entus/MZFormSheetController.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 6C955D289CBA1732476159B45995922140378636 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 6C955D289CBA1732476159B45995922140378636 36 | IDESourceControlWCCName 37 | MZFormSheetController 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Base.lproj/Main_iPad.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 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 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/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 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/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 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/buttons.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "buttons.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "buttons@2x.png" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/buttons.imageset/buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/buttons.imageset/buttons.png -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/buttons.imageset/buttons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/buttons.imageset/buttons@2x.png -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/calendar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "calendar.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "calendar@2x.png" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/calendar.imageset/calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/calendar.imageset/calendar.png -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/calendar.imageset/calendar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/calendar.imageset/calendar@2x.png -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/map.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "map.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "map@2x.png" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/map.imageset/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/map.imageset/map.png -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/map.imageset/map@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Images.xcassets/map.imageset/map@2x.png -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Launch Screen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZAppDelegate.h 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 13.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZAppDelegate.m 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 13.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import "MZAppDelegate.h" 10 | #import "MZFormSheetController.h" 11 | 12 | @implementation MZAppDelegate 13 | 14 | 15 | - (UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)size 16 | { 17 | UIImage *img = nil; 18 | 19 | CGRect rect = CGRectMake(0, 0, size.width, size.height); 20 | UIGraphicsBeginImageContext(rect.size); 21 | CGContextRef context = UIGraphicsGetCurrentContext(); 22 | CGContextSetFillColorWithColor(context, 23 | color.CGColor); 24 | CGContextFillRect(context, rect); 25 | 26 | img = UIGraphicsGetImageFromCurrentImageContext(); 27 | 28 | UIGraphicsEndImageContext(); 29 | 30 | return img; 31 | } 32 | 33 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 34 | - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 35 | #else 36 | - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 37 | #endif 38 | { 39 | NSUInteger orientations = UIInterfaceOrientationMaskAll; 40 | 41 | if ([MZFormSheetController formSheetControllersStack] > 0) { 42 | MZFormSheetController *viewController = [[MZFormSheetController formSheetControllersStack] lastObject]; 43 | return [viewController.presentedFSViewController supportedInterfaceOrientations]; 44 | } 45 | 46 | return orientations; 47 | } 48 | 49 | 50 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 51 | { 52 | [[UINavigationBar appearance] setBackgroundImage:[self imageWithColor:[UIColor whiteColor] andSize:CGSizeMake(1, 1)] forBarMetrics:UIBarMetricsDefault]; 53 | [[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor blackColor], NSForegroundColorAttributeName 54 | ,nil] forState:UIControlStateNormal]; 55 | 56 | 57 | // Override point for customization after application launch. 58 | return YES; 59 | } 60 | 61 | - (void)applicationWillResignActive:(UIApplication *)application 62 | { 63 | // 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. 64 | // 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. 65 | } 66 | 67 | - (void)applicationDidEnterBackground:(UIApplication *)application 68 | { 69 | // 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. 70 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 71 | } 72 | 73 | - (void)applicationWillEnterForeground:(UIApplication *)application 74 | { 75 | // 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. 76 | } 77 | 78 | - (void)applicationDidBecomeActive:(UIApplication *)application 79 | { 80 | // 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. 81 | } 82 | 83 | - (void)applicationWillTerminate:(UIApplication *)application 84 | { 85 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZCustomTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZCustomTransition.h 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 21.12.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MZFormSheetTransition.h" 11 | #import "MZFormSheetController.h" 12 | 13 | @interface MZCustomTransition : MZFormSheetTransition 14 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler; 15 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler; 16 | @end 17 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZCustomTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZCustomTransition.m 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 21.12.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import "MZCustomTransition.h" 10 | 11 | @implementation MZCustomTransition 12 | 13 | 14 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 15 | { 16 | CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; 17 | bounceAnimation.fillMode = kCAFillModeBoth; 18 | bounceAnimation.removedOnCompletion = YES; 19 | bounceAnimation.duration = 0.4; 20 | bounceAnimation.values = @[ 21 | [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.01f, 0.01f, 0.01f)], 22 | [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9f, 0.9f, 0.9f)], 23 | [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.1f)], 24 | [NSValue valueWithCATransform3D:CATransform3DIdentity]]; 25 | bounceAnimation.keyTimes = @[@0.0f, @0.5f, @0.75f, @1.0f]; 26 | bounceAnimation.timingFunctions = @[ 27 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], 28 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], 29 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 30 | bounceAnimation.delegate = self; 31 | [bounceAnimation setValue:completionHandler forKey:@"completionHandler"]; 32 | [formSheetController.presentedFSViewController.view.layer addAnimation:bounceAnimation forKey:@"bounce"]; 33 | 34 | 35 | 36 | } 37 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 38 | { 39 | CGRect formSheetRect = formSheetController.presentedFSViewController.view.frame; 40 | formSheetRect.origin.x = formSheetController.view.bounds.size.width; 41 | 42 | // shadow optimalization 43 | // CGPathRef fromPath = [UIBezierPath bezierPathWithRoundedRect:formSheetController.presentedFSViewController.view.frame cornerRadius:formSheetController.cornerRadius].CGPath; 44 | // CGPathRef toPath = [UIBezierPath bezierPathWithRoundedRect:formSheetRect cornerRadius:formSheetController.cornerRadius].CGPath; 45 | // 46 | // 47 | // formSheetController.view.layer.shadowPath = fromPath; 48 | 49 | // CABasicAnimation *shadowPathAnimation = [CABasicAnimation animationWithKeyPath:@"shadowPath"]; 50 | // shadowPathAnimation.duration = MZFormSheetControllerDefaultAnimationDuration; 51 | // shadowPathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 52 | // shadowPathAnimation.fromValue = (id) formSheetController.view.layer.shadowPath; 53 | // formSheetController.view.layer.shadowPath = toPath; 54 | // shadowPathAnimation.toValue = (id) formSheetController.view.layer.shadowPath; 55 | // [formSheetController.view.layer addAnimation:shadowPathAnimation forKey:@"shadowPath"]; 56 | 57 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 58 | delay:0 59 | options:UIViewAnimationOptionCurveEaseIn 60 | animations:^{ 61 | formSheetController.presentedFSViewController.view.frame = formSheetRect; 62 | } 63 | completion:^(BOOL finished) { 64 | completionHandler(); 65 | }]; 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZModalViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZModalViewController.h 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 13.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZModalViewController : UIViewController 12 | @property (nonatomic, assign) BOOL showStatusBar; 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZModalViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZModalViewController.m 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 13.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import "MZModalViewController.h" 10 | #import "MZFormSheetController.h" 11 | 12 | 13 | @interface MZModalViewController () 14 | 15 | @end 16 | 17 | @implementation MZModalViewController 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | 23 | } 24 | 25 | - (void)viewWillAppear:(BOOL)animated 26 | { 27 | [super viewWillAppear:animated]; 28 | 29 | // Access to form sheet controller 30 | MZFormSheetController *controller = self.navigationController.formSheetController; 31 | controller.shouldDismissOnBackgroundViewTap = YES; 32 | 33 | } 34 | 35 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 36 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations 37 | #else 38 | - (NSUInteger)supportedInterfaceOrientations 39 | #endif 40 | { 41 | return UIInterfaceOrientationMaskAll; 42 | } 43 | 44 | - (void)viewDidAppear:(BOOL)animated 45 | { 46 | [super viewDidAppear:animated]; 47 | 48 | self.showStatusBar = YES; 49 | [UIView animateWithDuration:0.3 animations:^{ 50 | [self.navigationController.formSheetController setNeedsStatusBarAppearanceUpdate]; 51 | }]; 52 | 53 | } 54 | 55 | - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation 56 | { 57 | return UIStatusBarAnimationSlide; 58 | } 59 | 60 | -(UIStatusBarStyle)preferredStatusBarStyle { 61 | return UIStatusBarStyleLightContent; // your own style 62 | } 63 | 64 | - (BOOL)prefersStatusBarHidden { 65 | // return self.showStatusBar; // your own visibility code 66 | return NO; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZNavigationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZNavigationViewController.h 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 23.10.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZNavigationViewController : UINavigationController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZNavigationViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZNavigationViewController.m 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 23.10.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import "MZNavigationViewController.h" 10 | 11 | @interface MZNavigationViewController () 12 | 13 | @end 14 | 15 | @implementation MZNavigationViewController 16 | 17 | - (void)viewDidLoad 18 | { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view. 21 | } 22 | 23 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 24 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations 25 | #else 26 | - (NSUInteger)supportedInterfaceOrientations 27 | #endif 28 | { 29 | return [self.topViewController supportedInterfaceOrientations]; 30 | } 31 | 32 | //-(UIStatusBarStyle)preferredStatusBarStyle { 33 | // return UIStatusBarStyleLightContent; // your own style 34 | //} 35 | 36 | //- (BOOL)prefersStatusBarHidden { 37 | // return YES; // your own visibility code 38 | //} 39 | 40 | - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 41 | [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; 42 | 43 | } 44 | 45 | - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 46 | [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; 47 | 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZTableViewController.h 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 03.01.2014. 6 | // Copyright (c) 2014 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZTableViewController : UITableViewController 12 | @property (weak, nonatomic) IBOutlet UITextField *textField; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZTableViewController.m 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 03.01.2014. 6 | // Copyright (c) 2014 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import "MZTableViewController.h" 10 | #import "MZFormSheetController.h" 11 | 12 | @interface MZTableViewController () 13 | 14 | @end 15 | 16 | @implementation MZTableViewController 17 | 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | 23 | [self.textField becomeFirstResponder]; 24 | 25 | [UIView animateWithDuration:0.3 animations:^{ 26 | [self.navigationController.formSheetController setNeedsStatusBarAppearanceUpdate]; 27 | }]; 28 | } 29 | 30 | 31 | -(UIStatusBarStyle)preferredStatusBarStyle { 32 | return UIStatusBarStyleLightContent; // your own style 33 | } 34 | 35 | - (BOOL)prefersStatusBarHidden { 36 | return NO; // your own visibility code 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZViewController.h 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 13.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZViewController : UIViewController 12 | - (IBAction)showFormSheet:(UIButton *)sender; 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/MZViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZViewController.m 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 13.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import "MZViewController.h" 10 | #import "MZFormSheetController.h" 11 | #import "MZCustomTransition.h" 12 | #import "MZModalViewController.h" 13 | #import "MZFormSheetSegue.h" 14 | 15 | @interface MZViewController () 16 | 17 | @end 18 | 19 | @implementation MZViewController 20 | 21 | - (void)viewDidLoad 22 | { 23 | [super viewDidLoad]; 24 | 25 | [[MZFormSheetBackgroundWindow appearance] setBackgroundBlurEffect:YES]; 26 | [[MZFormSheetBackgroundWindow appearance] setBlurRadius:5.0]; 27 | [[MZFormSheetBackgroundWindow appearance] setBackgroundColor:[UIColor clearColor]]; 28 | 29 | [MZFormSheetController registerTransitionClass:[MZCustomTransition class] forTransitionStyle:MZFormSheetTransitionStyleCustom]; 30 | } 31 | 32 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 33 | { 34 | if ([segue.identifier isEqualToString:@"formSheet"]) { 35 | MZFormSheetSegue *formSheetSegue = (MZFormSheetSegue *)segue; 36 | MZFormSheetController *formSheet = formSheetSegue.formSheetController; 37 | formSheet.transitionStyle = MZFormSheetTransitionStyleBounce; 38 | formSheet.cornerRadius = 8.0; 39 | formSheet.didTapOnBackgroundViewCompletionHandler = ^(CGPoint location) { 40 | 41 | }; 42 | 43 | formSheet.shouldDismissOnBackgroundViewTap = YES; 44 | 45 | formSheet.didPresentCompletionHandler = ^(UIViewController *presentedFSViewController) { 46 | 47 | }; 48 | } 49 | } 50 | 51 | - (IBAction)showFormSheet:(UIButton *)sender 52 | { 53 | UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"modal"]; 54 | 55 | MZFormSheetController *formSheet = [[MZFormSheetController alloc] initWithViewController:vc]; 56 | 57 | formSheet.presentedFormSheetSize = CGSizeMake(300, 298); 58 | // formSheet.transitionStyle = MZFormSheetTransitionStyleSlideFromTop; 59 | formSheet.shadowRadius = 2.0; 60 | formSheet.shadowOpacity = 0.3; 61 | formSheet.shouldDismissOnBackgroundViewTap = YES; 62 | formSheet.shouldCenterVertically = YES; 63 | formSheet.movementWhenKeyboardAppears = MZFormSheetWhenKeyboardAppearsCenterVertically; 64 | // formSheet.keyboardMovementStyle = MZFormSheetKeyboardMovementStyleMoveToTop; 65 | // formSheet.keyboardMovementStyle = MZFormSheetKeyboardMovementStyleMoveToTopInset; 66 | // formSheet.landscapeTopInset = 50; 67 | // formSheet.portraitTopInset = 100; 68 | 69 | __weak MZFormSheetController *weakFormSheet = formSheet; 70 | 71 | 72 | // If you want to animate status bar use this code 73 | formSheet.didTapOnBackgroundViewCompletionHandler = ^(CGPoint location) { 74 | UINavigationController *navController = (UINavigationController *)weakFormSheet.presentedFSViewController; 75 | if ([navController.topViewController isKindOfClass:[MZModalViewController class]]) { 76 | MZModalViewController *mzvc = (MZModalViewController *)navController.topViewController; 77 | mzvc.showStatusBar = NO; 78 | } 79 | 80 | 81 | [UIView animateWithDuration:0.3 animations:^{ 82 | if ([weakFormSheet respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { 83 | [weakFormSheet setNeedsStatusBarAppearanceUpdate]; 84 | } 85 | }]; 86 | }; 87 | 88 | formSheet.willPresentCompletionHandler = ^(UIViewController *presentedFSViewController) { 89 | // Passing data 90 | UINavigationController *navController = (UINavigationController *)presentedFSViewController; 91 | navController.topViewController.title = @"PASSING DATA"; 92 | }; 93 | formSheet.transitionStyle = MZFormSheetTransitionStyleCustom; 94 | 95 | [MZFormSheetController sharedBackgroundWindow].formSheetBackgroundWindowDelegate = self; 96 | 97 | [self mz_presentFormSheetController:formSheet animated:YES completionHandler:^(MZFormSheetController *formSheetController) { 98 | 99 | }]; 100 | } 101 | 102 | -(UIStatusBarStyle)preferredStatusBarStyle { 103 | return UIStatusBarStyleLightContent; // your own style 104 | } 105 | 106 | - (BOOL)prefersStatusBarHidden { 107 | return NO; // your own visibility code 108 | } 109 | 110 | - (void)formSheetBackgroundWindow:(MZFormSheetBackgroundWindow *)formSheetBackgroundWindow didChangeStatusBarToOrientation:(UIInterfaceOrientation)orientation 111 | { 112 | NSLog(@"%@",NSStringFromSelector(_cmd)); 113 | } 114 | 115 | - (void)formSheetBackgroundWindow:(MZFormSheetBackgroundWindow *)formSheetBackgroundWindow didChangeStatusBarFrame:(CGRect)newStatusBarFrame 116 | { 117 | NSLog(@"%@",NSStringFromSelector(_cmd)); 118 | } 119 | 120 | - (void)formSheetBackgroundWindow:(MZFormSheetBackgroundWindow *)formSheetBackgroundWindow didRotateToOrientation:(UIDeviceOrientation)orientation animated:(BOOL)animated 121 | { 122 | NSLog(@"%@",NSStringFromSelector(_cmd)); 123 | } 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Xcode5Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSApplicationCategoryType 26 | 27 | LSRequiresIPhoneOS 28 | 29 | UILaunchStoryboardName 30 | Launch Screen 31 | UIMainStoryboardFile 32 | Main_iPhone 33 | UIMainStoryboardFile~ipad 34 | Main_iPad 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UISupportedInterfaceOrientations 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | UISupportedInterfaceOrientations~ipad 46 | 47 | UIInterfaceOrientationPortrait 48 | UIInterfaceOrientationPortraitUpsideDown 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/Xcode5Example-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 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5Example/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 13.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "MZAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([MZAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5ExampleTests/Xcode5ExampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5ExampleTests/Xcode5ExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Xcode5ExampleTests.m 3 | // Xcode5ExampleTests 4 | // 5 | // Created by Michał Zaborowski on 13.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Xcode5ExampleTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Xcode5ExampleTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Example/Xcode5 iOS 7 Example/Xcode5Example/Xcode5ExampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Michał Zaborowski 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | The Software is provided "as is", without warranty of any kind, express or 14 | implied, including but not limited to the warranties of merchantability, 15 | fitness for a particular purpose and noninfringement. In no event shall the 16 | authors or copyright holders be liable for any claim, damages or other 17 | liability, whether in an action of contract, tort or otherwise, arising from, 18 | out of or in connection with the software or the use or other dealings in 19 | the Software. -------------------------------------------------------------------------------- /MZFormSheetController+SVProgressHUD/MZFormSheetController+SVProgressHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressHUD+MZFormSheetController.h 3 | // BookWhiz 4 | // 5 | // Created by Michał Zaborowski on 25.07.2014. 6 | // Copyright (c) 2014 Railwaymen. All rights reserved. 7 | // 8 | 9 | #import "MZFormSheetController.h" 10 | 11 | @interface MZFormSheetController (SVProgressHUD) 12 | @end 13 | -------------------------------------------------------------------------------- /MZFormSheetController+SVProgressHUD/MZFormSheetController+SVProgressHUD.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVProgressHUD+MZFormSheetController.m 3 | // BookWhiz 4 | // 5 | // Created by Michał Zaborowski on 25.07.2014. 6 | // Copyright (c) 2014 Railwaymen. All rights reserved. 7 | // 8 | 9 | #import "MZFormSheetController+SVProgressHUD.h" 10 | #import "SVProgressHUD.h" 11 | 12 | @interface SVProgressHUD () 13 | + (SVProgressHUD*)sharedView; 14 | - (UIControl *)overlayView; 15 | @end 16 | 17 | @interface MZProgressHUDObserver : NSObject 18 | @end 19 | 20 | @implementation MZProgressHUDObserver 21 | 22 | - (instancetype)init 23 | { 24 | if (self = [super init]) { 25 | [[NSNotificationCenter defaultCenter] addObserverForName:SVProgressHUDWillAppearNotification object:nil queue:nil usingBlock:^(NSNotification *note) { 26 | 27 | for (UIWindow *window in [[UIApplication sharedApplication] windows]) { 28 | if(![[window class] isEqual:[MZFormSheetBackgroundWindow class]]) { 29 | 30 | MZFormSheetController *formSheet = [[MZFormSheetController formSheetControllersStack] lastObject]; 31 | if(formSheet){ 32 | [[SVProgressHUD sharedView].overlayView removeFromSuperview]; 33 | [formSheet.formSheetWindow addSubview:[SVProgressHUD sharedView].overlayView]; 34 | } 35 | break; 36 | 37 | } 38 | } 39 | }]; 40 | } 41 | return self; 42 | } 43 | 44 | @end 45 | 46 | @implementation MZFormSheetController (SVProgressHUD) 47 | 48 | + (void)load 49 | { 50 | [self sharedHUDObserver]; 51 | } 52 | 53 | + (MZProgressHUDObserver *)sharedHUDObserver { 54 | static MZProgressHUDObserver *_sharedHUDObserver = nil; 55 | static dispatch_once_t onceToken; 56 | dispatch_once(&onceToken, ^{ 57 | _sharedHUDObserver = [[MZProgressHUDObserver alloc] init]; 58 | }); 59 | 60 | return _sharedHUDObserver; 61 | } 62 | 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /MZFormSheetController.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'MZFormSheetController' 3 | s.version = '3.1.3' 4 | s.license = 'MIT' 5 | s.summary = 'Provides an alternative to the native iOS UIModalPresentationFormSheet.' 6 | s.homepage = 'https://github.com/m1entus/MZFormSheetController' 7 | s.authors = 'Michał Zaborowski' 8 | s.source = { :git => 'https://github.com/m1entus/MZFormSheetController.git', :tag => s.version.to_s } 9 | s.default_subspec = 'Core' 10 | s.requires_arc = true 11 | s.deprecated_in_favor_of = 'MZFormSheetPresentationController' 12 | s.dependency 'MZAppearance' 13 | 14 | s.subspec "Core" do |sp| 15 | sp.source_files = 'MZFormSheetController/*.{h,m}' 16 | end 17 | 18 | s.subspec "SVProgressHUD" do |sp| 19 | sp.source_files = "MZFormSheetController+SVProgressHUD/*.{h,m}" 20 | sp.dependency 'SVProgressHUD' 21 | sp.dependency 'MZFormSheetController/Core' 22 | end 23 | 24 | s.platform = :ios, '6.1' 25 | s.frameworks = 'QuartzCore', 'Accelerate' 26 | end 27 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetBackgroundWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZFormSheetBackgroundWindow.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 31.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | #import 28 | 29 | extern UIWindowLevel const MZFormSheetBackgroundWindowLevelAboveStatusBar; 30 | extern UIWindowLevel const MZFormSheetBackgroundWindowLevelBelowStatusBar; 31 | 32 | @class MZFormSheetBackgroundWindow; 33 | 34 | @protocol MZFormSheetBackgroundWindowDelegate 35 | @optional 36 | /** 37 | * Called when the orientation of the device changes. 38 | * 39 | * @param formSheetBackgroundWindow Form sheet background window. 40 | * @param orientation Returns the physical orientation of the device. 41 | */ 42 | - (void)formSheetBackgroundWindow:(nonnull MZFormSheetBackgroundWindow *)formSheetBackgroundWindow didRotateToOrientation:(UIDeviceOrientation)orientation animated:(BOOL)animated; 43 | 44 | /** 45 | * Called when the frame of the status bar changes. 46 | * 47 | * @param formSheetBackgroundWindow Form sheet background window. 48 | * @param newStatusBarFrame Expressing the location and size of the new status bar frame. 49 | */ 50 | - (void)formSheetBackgroundWindow:(nonnull MZFormSheetBackgroundWindow *)formSheetBackgroundWindow didChangeStatusBarFrame:(CGRect)newStatusBarFrame; 51 | 52 | /** 53 | * Called when the orientation of the application's user interface changes. 54 | * This method is called inside an animation block. 55 | * 56 | * @param formSheetBackgroundWindow Form sheet background window. 57 | * @param orientation The orientation of the application's user interface. 58 | */ 59 | - (void)formSheetBackgroundWindow:(nonnull MZFormSheetBackgroundWindow *)formSheetBackgroundWindow didChangeStatusBarToOrientation:(UIInterfaceOrientation)orientation; 60 | @end 61 | 62 | @interface MZFormSheetBackgroundWindow : UIWindow 63 | 64 | /** 65 | * The object that acts as the delegate of the receiving form sheet background window. 66 | */ 67 | @property (nonatomic, weak, nullable) id formSheetBackgroundWindowDelegate; 68 | 69 | /** 70 | The positioning of windows relative to each other. 71 | If you want to cover status bar when a dialog is presented use MZFormSheetBackgroundWindowLevelAboveStatusBar 72 | (recomended for UIStatusBarStyleLightContent or if you don't use blur) 73 | 74 | extern UIWindowLevel const MZFormSheetBackgroundWindowLevelAboveStatusBar; 75 | extern UIWindowLevel const MZFormSheetBackgroundWindowLevelBelowStatusBar; 76 | 77 | By default, this is MZFormSheetBackgroundWindowLevelBelowStatusBar; 78 | */ 79 | @property (nonatomic, readwrite) UIWindowLevel windowLevel MZ_APPEARANCE_SELECTOR; 80 | 81 | /** 82 | The background color of the background view. 83 | After last form sheet dismiss, backgroundColor will change to default. 84 | If you want to set it permanently to another color use appearance proxy on MZFormSheetBackgroundWindow. 85 | By default, this is a black at with a 0.5 alpha component 86 | */ 87 | @property (nonatomic, strong, nullable) UIColor *backgroundColor MZ_APPEARANCE_SELECTOR; 88 | 89 | /** 90 | The background image of the background view, it is setter for backgroundImageView and can be set by MZAppearance proxy. 91 | After last form sheet dismiss, backgroundImage will change to default. 92 | If you want to set it permanently to another color use appearance proxy on MZFormSheetBackgroundWindow. 93 | By default, this is nil 94 | */ 95 | @property (nonatomic, strong, nullable) UIImage *backgroundImage MZ_APPEARANCE_SELECTOR; 96 | 97 | /** 98 | The background image view. 99 | */ 100 | @property (nonatomic, strong, readonly, nonnull) UIImageView *backgroundImageView; 101 | 102 | /* 103 | Apply background blur effect 104 | By default, this is NO 105 | */ 106 | @property (nonatomic, assign) BOOL backgroundBlurEffect MZ_APPEARANCE_SELECTOR; 107 | 108 | /* 109 | Apply native background blur effect, you have to set backgroundBlurEffect to YES to apply blur! 110 | By default, this is YES for iOS8, it is only available for iOS8 111 | */ 112 | @property (nonatomic, assign) BOOL shouldUseNativeBlurEffect MZ_APPEARANCE_SELECTOR; 113 | 114 | /* 115 | Native blur effect style, available from iOS8 116 | */ 117 | @property (nonatomic, assign) UIBlurEffectStyle blurEffectStyle NS_AVAILABLE_IOS(8_0) MZ_APPEARANCE_SELECTOR; 118 | 119 | /* 120 | Specifies the blur radius used to render the blur background view 121 | By default, this is 2.0 122 | */ 123 | @property (nonatomic, assign) CGFloat blurRadius MZ_APPEARANCE_SELECTOR; 124 | 125 | /* 126 | Specifies the blur tint color used to render the blur background view 127 | By default, this is nil 128 | */ 129 | @property (nonatomic, strong, nullable) UIColor *blurTintColor MZ_APPEARANCE_SELECTOR; 130 | 131 | /* 132 | Specifies the blur saturation used to render the blur background view 133 | By default, this is 1.0 134 | */ 135 | @property (nonatomic, assign) CGFloat blurSaturation MZ_APPEARANCE_SELECTOR; 136 | 137 | /* 138 | Specifies the blur mask image used to render the blur background view 139 | By default, this is nil 140 | */ 141 | @property (nonatomic, strong, nullable) UIImage *blurMaskImage MZ_APPEARANCE_SELECTOR; 142 | 143 | /* 144 | Asynchronously recompute the display of background blur. 145 | Recommended to use if you expect interface orientation or some dynamic animations belof form sheet 146 | By default, this is NO 147 | */ 148 | @property (nonatomic, assign) BOOL dynamicBlur MZ_APPEARANCE_SELECTOR; 149 | 150 | /* 151 | Specifies how often the blur background refresh. 152 | Works only if dynamicBlur is set to YES. 153 | By default, this is 0 154 | */ 155 | @property (nonatomic, assign) CGFloat dynamicBlurInterval MZ_APPEARANCE_SELECTOR; 156 | 157 | /* 158 | All of the interface orientations that the background image view supports. 159 | By default, this is UIInterfaceOrientationMaskAll 160 | */ 161 | @property (nonatomic, assign) UIInterfaceOrientationMask supportedInterfaceOrientations MZ_APPEARANCE_SELECTOR; 162 | @end 163 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetBackgroundWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZFormSheetBackgroundWindow.m 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 31.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "MZFormSheetBackgroundWindow.h" 27 | #import 28 | #import "UIImage+Additional.h" 29 | #import "MZMacro.h" 30 | 31 | CGFloat const MZFormSheetControllerDefaultBackgroundOpacity = 0.5; 32 | CGFloat const MZFormSheetControllerDefaultBackgroundBlurRadius = 2.0; 33 | CGFloat const MZFormSheetControllerDefaultBackgroundBlurSaturation = 1.0; 34 | 35 | UIWindowLevel const MZFormSheetBackgroundWindowLevelAboveStatusBar = 1002; 36 | UIWindowLevel const MZFormSheetBackgroundWindowLevelBelowStatusBar = 2; 37 | 38 | extern CGFloat MZFormSheetControllerWindowTag; 39 | 40 | static CGFloat const UIInterfaceOrientationAngleOfOrientation(UIInterfaceOrientation orientation) { 41 | 42 | switch (orientation) 43 | { 44 | case UIInterfaceOrientationPortraitUpsideDown: return M_PI; 45 | case UIInterfaceOrientationLandscapeLeft: return -M_PI_2; 46 | case UIInterfaceOrientationLandscapeRight: return M_PI_2; 47 | default: return 0.0f; 48 | } 49 | } 50 | 51 | static UIInterfaceOrientationMask const UIInterfaceOrientationMaskFromOrientation(UIInterfaceOrientation orientation) { 52 | return 1 << orientation; 53 | } 54 | 55 | #pragma mark - MZFormSheetBackgroundWindow 56 | 57 | @interface MZFormSheetBackgroundWindow() 58 | @property (nonatomic, strong) UIImageView *backgroundImageView; 59 | @property (nonatomic, assign, getter = isUpdatingBlur) BOOL updatingBlur; 60 | @property (nonatomic, assign) UIInterfaceOrientation lastWindowOrientation; 61 | @property (nonatomic, strong) UIVisualEffectView *blurBackgroundView; 62 | @end 63 | 64 | @implementation MZFormSheetBackgroundWindow 65 | @synthesize backgroundColor = _backgroundColor; 66 | @synthesize windowLevel; 67 | 68 | #pragma mark - Class methods 69 | 70 | #pragma clang diagnostic push 71 | #pragma clang diagnostic ignored "-Wwarning-flag" 72 | 73 | + (void)initialize 74 | { 75 | if (self == [MZFormSheetBackgroundWindow class]) { 76 | [[self appearance] setBackgroundColor:[UIColor colorWithWhite:0 alpha:MZFormSheetControllerDefaultBackgroundOpacity]]; 77 | [[self appearance] setBlurRadius:MZFormSheetControllerDefaultBackgroundBlurRadius]; 78 | [[self appearance] setBlurSaturation:MZFormSheetControllerDefaultBackgroundBlurSaturation]; 79 | [[self appearance] setWindowLevel:MZFormSheetBackgroundWindowLevelBelowStatusBar]; 80 | [[self appearance] setShouldUseNativeBlurEffect:YES]; 81 | if (MZSystemVersionGreaterThanOrEqualTo_iOS8()) { 82 | [[self appearance] setBlurEffectStyle:UIBlurEffectStyleLight]; 83 | } 84 | [[self appearance] setDynamicBlur:NO]; 85 | [[self appearance] setDynamicBlurInterval:0.0f]; 86 | } 87 | } 88 | 89 | #pragma clang diagnostic pop 90 | 91 | + (instancetype)appearance 92 | { 93 | return [MZAppearance appearanceForClass:[self class]]; 94 | } 95 | 96 | + (UIImage *)screenshotUsingContext:(BOOL)useContext 97 | { 98 | // Create a graphics context with the target size 99 | UIGraphicsBeginImageContextWithOptions([[UIScreen mainScreen] bounds].size, NO, 0); 100 | 101 | CGContextRef context = UIGraphicsGetCurrentContext(); 102 | 103 | // Iterate over every window from back to front 104 | for (UIWindow *window in [[UIApplication sharedApplication] windows]) 105 | { 106 | if ((![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen]) && window.tag != MZFormSheetControllerWindowTag && ![window isKindOfClass:[MZFormSheetBackgroundWindow class]]) 107 | { 108 | if (CGRectEqualToRect(window.bounds, CGRectZero)){ 109 | continue; 110 | } 111 | // -renderInContext: renders in the coordinate space of the layer, 112 | // so we must first apply the layer's geometry to the graphics context 113 | CGContextSaveGState(context); 114 | // Center the context around the window's anchor point 115 | CGContextTranslateCTM(context, [window center].x, [window center].y); 116 | // Apply the window's transform about the anchor point 117 | CGContextConcatCTM(context, [window transform]); 118 | // Offset by the portion of the bounds left of and above the anchor point 119 | CGContextTranslateCTM(context, 120 | -[window bounds].size.width * [[window layer] anchorPoint].x, 121 | -[window bounds].size.height * [[window layer] anchorPoint].y); 122 | 123 | if (useContext) { 124 | // Render the layer hierarchy to the current context 125 | [[window layer] renderInContext:context]; 126 | } else { 127 | if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { 128 | [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:NO]; 129 | } else { 130 | [[window layer] renderInContext:context]; 131 | } 132 | } 133 | 134 | 135 | // Restore the context 136 | CGContextRestoreGState(context); 137 | } 138 | } 139 | 140 | // Retrieve the screenshot image 141 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 142 | 143 | UIGraphicsEndImageContext(); 144 | 145 | return image; 146 | } 147 | 148 | #pragma mark - Setters 149 | 150 | - (void)setSupportedInterfaceOrientations:(UIInterfaceOrientationMask)supportedInterfaceOrientations 151 | { 152 | _supportedInterfaceOrientations = supportedInterfaceOrientations; 153 | 154 | [self rotateWindow]; 155 | } 156 | 157 | - (void)setBackgroundColor:(UIColor *)backgroundColor 158 | { 159 | _backgroundColor = backgroundColor; 160 | [super setBackgroundColor:backgroundColor]; 161 | } 162 | 163 | - (void)setShouldUseNativeBlurEffect:(BOOL)shouldUseNativeBlurEffect { 164 | if (_shouldUseNativeBlurEffect != shouldUseNativeBlurEffect) { 165 | if (MZSystemVersionGreaterThanOrEqualTo_iOS8()) { 166 | _shouldUseNativeBlurEffect = shouldUseNativeBlurEffect; 167 | } else { 168 | _shouldUseNativeBlurEffect = NO; 169 | } 170 | } 171 | } 172 | 173 | - (void)setBackgroundImage:(UIImage *)backgroundImage 174 | { 175 | if (self.backgroundImageView) { 176 | self.backgroundImageView.image = backgroundImage; 177 | } else { 178 | _backgroundImage = backgroundImage; 179 | } 180 | 181 | } 182 | 183 | - (void)setBackgroundBlurEffect:(BOOL)backgroundBlurEffect 184 | { 185 | if (_backgroundBlurEffect != backgroundBlurEffect) { 186 | if (_backgroundBlurEffect && !backgroundBlurEffect) { 187 | self.backgroundImageView.image = [[UIImage alloc] init]; 188 | } 189 | 190 | _backgroundBlurEffect = backgroundBlurEffect; 191 | 192 | if (self.dynamicBlur) { 193 | [self updateBlurAsynchronously]; 194 | } 195 | } 196 | } 197 | 198 | - (void)setDynamicBlur:(BOOL)dynamicBlur 199 | { 200 | if (_dynamicBlur != dynamicBlur) { 201 | _dynamicBlur = dynamicBlur; 202 | if (dynamicBlur) 203 | { 204 | [self updateBlurAsynchronously]; 205 | } 206 | } 207 | } 208 | 209 | #pragma mark - Getters 210 | 211 | - (UIColor *)backgroundColor 212 | { 213 | return _backgroundColor; 214 | } 215 | 216 | #pragma mark - Initializers 217 | 218 | - (void)makeKeyAndVisible 219 | { 220 | [super makeKeyAndVisible]; 221 | 222 | if (self.backgroundBlurEffect) { 223 | [self updateBlurUsingContext:NO]; 224 | } 225 | } 226 | 227 | - (instancetype)initWithFrame:(CGRect)frame 228 | { 229 | if (self = [super initWithFrame:frame]) { 230 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 231 | self.opaque = NO; 232 | 233 | id appearance = [[self class] appearance]; 234 | [appearance applyInvocationTo:self]; 235 | 236 | _supportedInterfaceOrientations = UIInterfaceOrientationMaskAll; 237 | 238 | _backgroundImageView = [[UIImageView alloc] initWithFrame:frame]; 239 | _backgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 240 | 241 | _backgroundImageView.image = _backgroundImage; 242 | 243 | [self addSubview:_backgroundImageView]; 244 | 245 | [_backgroundImageView addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:NULL]; 246 | 247 | [self rotateWindow]; 248 | 249 | self.lastWindowOrientation = [self windowOrientation]; 250 | 251 | [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 252 | 253 | [[NSNotificationCenter defaultCenter] addObserver:self 254 | selector:@selector(didChangeStatusBarOrientationNotificationHandler:) 255 | name:UIApplicationDidChangeStatusBarOrientationNotification 256 | object:nil]; 257 | 258 | [[NSNotificationCenter defaultCenter] addObserver:self 259 | selector:@selector(didChangeStatusBarFrameNotificationHandler:) 260 | name:UIApplicationDidChangeStatusBarFrameNotification 261 | object:nil]; 262 | 263 | [[NSNotificationCenter defaultCenter] addObserver:self 264 | selector:@selector(didOrientationChangeNotificationHandler:) 265 | name:UIDeviceOrientationDidChangeNotification 266 | object:nil]; 267 | 268 | [[NSNotificationCenter defaultCenter] addObserver:self 269 | selector:@selector(willEnterForegroundNotification:) 270 | name:UIApplicationWillEnterForegroundNotification object:nil]; 271 | 272 | } 273 | return self; 274 | } 275 | 276 | - (void)willEnterForegroundNotification:(NSNotification *)notification { 277 | if (self.shouldUseNativeBlurEffect) { 278 | self.hidden = YES; 279 | [self makeKeyAndVisible]; 280 | } 281 | } 282 | 283 | #pragma mark - Notification handlers 284 | 285 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 286 | { 287 | if ([object isEqual:self.backgroundImageView] && [keyPath isEqualToString:@"image"]) 288 | { 289 | _backgroundImage = change[@"new"]; 290 | } 291 | } 292 | 293 | - (void)didOrientationChangeNotificationHandler:(NSNotification *)notification 294 | { 295 | [self rotateWindow]; 296 | 297 | UIInterfaceOrientation windowOrientation = [self windowOrientation]; 298 | if (self.backgroundBlurEffect && windowOrientation != self.lastWindowOrientation) { 299 | self.lastWindowOrientation = windowOrientation; 300 | [self updateBlurUsingContext:YES]; 301 | } 302 | 303 | if ([self.formSheetBackgroundWindowDelegate respondsToSelector:@selector(formSheetBackgroundWindow:didRotateToOrientation:animated:)]) { 304 | BOOL animated = [notification.userInfo[@"UIDeviceOrientationRotateAnimatedUserInfoKey"] boolValue]; 305 | UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation]; 306 | 307 | [self.formSheetBackgroundWindowDelegate formSheetBackgroundWindow:self didRotateToOrientation:deviceOrientation animated:animated]; 308 | } 309 | } 310 | 311 | - (void)didChangeStatusBarOrientationNotificationHandler:(NSNotification *)notification 312 | { 313 | [self rotateWindow]; 314 | 315 | if ([self.formSheetBackgroundWindowDelegate respondsToSelector:@selector(formSheetBackgroundWindow:didChangeStatusBarToOrientation:)]) { 316 | NSNumber *orientation = notification.userInfo[UIApplicationStatusBarOrientationUserInfoKey]; 317 | [self.formSheetBackgroundWindowDelegate formSheetBackgroundWindow:self didChangeStatusBarToOrientation:[orientation integerValue]]; 318 | } 319 | } 320 | 321 | - (void)didChangeStatusBarFrameNotificationHandler:(NSNotification *)notification 322 | { 323 | // This notification is inside an animation block 324 | [self rotateWindow]; 325 | 326 | if ([self.formSheetBackgroundWindowDelegate respondsToSelector:@selector(formSheetBackgroundWindow:didChangeStatusBarFrame:)]) { 327 | NSValue *statusBarFrame = notification.userInfo[UIApplicationStatusBarFrameUserInfoKey]; 328 | [self.formSheetBackgroundWindowDelegate formSheetBackgroundWindow:self didChangeStatusBarFrame:[statusBarFrame CGRectValue]]; 329 | } 330 | } 331 | 332 | #pragma mark - Blur 333 | 334 | - (void)setupNativeBackgroundBlurView { 335 | [self.blurBackgroundView removeFromSuperview]; 336 | self.blurBackgroundView = nil; 337 | 338 | if (self.shouldUseNativeBlurEffect) { 339 | 340 | UIVisualEffect *visualEffect = [UIBlurEffect effectWithStyle:self.blurEffectStyle]; 341 | self.blurBackgroundView = [[UIVisualEffectView alloc] initWithEffect:visualEffect]; 342 | 343 | self.blurBackgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin; 344 | 345 | self.blurBackgroundView.frame = self.bounds; 346 | self.blurBackgroundView.translatesAutoresizingMaskIntoConstraints = YES; 347 | self.blurBackgroundView.userInteractionEnabled = NO; 348 | 349 | super.backgroundColor = [UIColor clearColor]; 350 | self.backgroundImageView.hidden = YES; 351 | [self insertSubview:self.blurBackgroundView atIndex:0]; 352 | } else { 353 | self.backgroundImageView.hidden = NO; 354 | super.backgroundColor = self.backgroundColor; 355 | } 356 | } 357 | 358 | - (UIImage *)rotateImageToStatusBarOrientation:(UIImage *)image 359 | { 360 | if (MZSystemVersionLessThan_iOS8()) { 361 | if ([self windowOrientation] == UIInterfaceOrientationLandscapeLeft) { 362 | return [image imageRotatedByDegrees:90]; 363 | } else if ([self windowOrientation] == UIInterfaceOrientationLandscapeRight) { 364 | return [image imageRotatedByDegrees:-90]; 365 | } else if ([self windowOrientation] == UIInterfaceOrientationPortraitUpsideDown) { 366 | return [image imageRotatedByDegrees:180]; 367 | } 368 | } 369 | 370 | return image; 371 | } 372 | 373 | - (void)updateBlurUsingContext:(BOOL)useContext 374 | { 375 | if (self.shouldUseNativeBlurEffect) { 376 | if (!self.blurBackgroundView) { 377 | [self setupNativeBackgroundBlurView]; 378 | } 379 | } else { 380 | UIImage *blurredImage = [[MZFormSheetBackgroundWindow screenshotUsingContext:useContext] blurredImageWithRadius:self.blurRadius tintColor:self.blurTintColor saturationDeltaFactor:self.blurSaturation maskImage:self.blurMaskImage]; 381 | 382 | self.backgroundImageView.image = [self rotateImageToStatusBarOrientation:blurredImage]; 383 | } 384 | } 385 | 386 | 387 | - (void)updateBlurAsynchronously 388 | { 389 | if (self.dynamicBlur && !self.isUpdatingBlur && self.backgroundBlurEffect && !self.shouldUseNativeBlurEffect) 390 | { 391 | UIImage *snapshot = [self rotateImageToStatusBarOrientation:[MZFormSheetBackgroundWindow screenshotUsingContext:YES]]; 392 | 393 | self.updatingBlur = YES; 394 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 395 | 396 | UIImage *blurredImage = [snapshot blurredImageWithRadius:self.blurRadius tintColor:self.blurTintColor saturationDeltaFactor:self.blurSaturation maskImage:self.blurMaskImage]; 397 | 398 | dispatch_sync(dispatch_get_main_queue(), ^{ 399 | 400 | self.updatingBlur = NO; 401 | if (self.dynamicBlur) 402 | { 403 | self.backgroundImageView.image = blurredImage; 404 | if (self.dynamicBlurInterval) 405 | { 406 | [self performSelector:@selector(updateBlurAsynchronously) withObject:nil 407 | afterDelay:self.dynamicBlurInterval inModes:@[NSDefaultRunLoopMode, UITrackingRunLoopMode]]; 408 | } 409 | else 410 | { 411 | [self performSelectorOnMainThread:@selector(updateBlurAsynchronously) withObject:nil 412 | waitUntilDone:NO modes:@[NSDefaultRunLoopMode, UITrackingRunLoopMode]]; 413 | } 414 | } 415 | }); 416 | }); 417 | } 418 | } 419 | 420 | #pragma mark - Window rotations 421 | 422 | - (void)rotateWindow 423 | { 424 | CGFloat angle = UIInterfaceOrientationAngleOfOrientation([self windowOrientation]); 425 | CGAffineTransform transform = CGAffineTransformMakeRotation(angle); 426 | 427 | [self makeTransform:transform forView:self.backgroundImageView inFrame:self.bounds]; 428 | } 429 | 430 | - (void)makeTransform:(CGAffineTransform)transform forView:(UIView *)view inFrame:(CGRect)frame 431 | { 432 | if(!CGAffineTransformEqualToTransform(view.transform, transform)) { 433 | view.transform = transform; 434 | } 435 | 436 | if(!CGRectEqualToRect(view.frame, frame)) { 437 | view.frame = frame; 438 | } 439 | } 440 | 441 | - (UIInterfaceOrientation)windowOrientation 442 | { 443 | UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation]; 444 | UIInterfaceOrientationMask statusBarOrientationAsMask = UIInterfaceOrientationMaskFromOrientation(statusBarOrientation); 445 | 446 | if(self.supportedInterfaceOrientations & statusBarOrientationAsMask) { 447 | return statusBarOrientation; 448 | 449 | } else { 450 | if(self.supportedInterfaceOrientations & UIInterfaceOrientationMaskPortrait) { 451 | return UIInterfaceOrientationPortrait; 452 | 453 | } else if(self.supportedInterfaceOrientations & UIInterfaceOrientationMaskLandscapeLeft) { 454 | return UIInterfaceOrientationLandscapeLeft; 455 | 456 | } else if(self.supportedInterfaceOrientations & UIInterfaceOrientationMaskLandscapeRight) { 457 | return UIInterfaceOrientationLandscapeRight; 458 | 459 | } else { 460 | return UIInterfaceOrientationPortraitUpsideDown; 461 | } 462 | } 463 | } 464 | 465 | #pragma mark - Dealloc 466 | 467 | - (void)dealloc 468 | { 469 | [self.backgroundImageView removeObserver:self forKeyPath:@"image"]; 470 | 471 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]; 472 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; 473 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; 474 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; 475 | 476 | [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; 477 | } 478 | 479 | @end 480 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetBackgroundWindowViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZTransition.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 13.01.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | 28 | @interface MZFormSheetBackgroundWindowViewController : UIViewController 29 | @property (nonatomic, assign) UIStatusBarStyle preferredStatusBarStyleForBackgroundWindow; 30 | @property (nonatomic, assign) BOOL prefersStatusBarHiddenForBackgroundWindow; 31 | 32 | + (instancetype)viewControllerWithPreferredStatusBarStyle:(UIStatusBarStyle)preferredStatusBarStyle 33 | prefersStatusBarHidden:(BOOL)prefersStatusBarHidden; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetBackgroundWindowViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZTransition.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 13.01.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "MZFormSheetBackgroundWindowViewController.h" 27 | 28 | @implementation MZFormSheetBackgroundWindowViewController 29 | 30 | + (instancetype)viewControllerWithPreferredStatusBarStyle:(UIStatusBarStyle)preferredStatusBarStyle 31 | prefersStatusBarHidden:(BOOL)prefersStatusBarHidden 32 | { 33 | MZFormSheetBackgroundWindowViewController *viewController = [[self alloc] init]; 34 | viewController.preferredStatusBarStyleForBackgroundWindow = preferredStatusBarStyle; 35 | viewController.prefersStatusBarHiddenForBackgroundWindow = prefersStatusBarHidden; 36 | return viewController; 37 | } 38 | 39 | - (UIStatusBarStyle)preferredStatusBarStyle { 40 | return self.preferredStatusBarStyleForBackgroundWindow; 41 | } 42 | 43 | - (BOOL)prefersStatusBarHidden { 44 | return self.prefersStatusBarHiddenForBackgroundWindow; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZFormSheetController.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 08.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | #import 28 | #import "MZFormSheetBackgroundWindow.h" 29 | #import "MZFormSheetTransition.h" 30 | #import "MZMacro.h" 31 | 32 | extern CGFloat const MZFormSheetControllerDefaultAnimationDuration; 33 | extern CGFloat const MZFormSheetControllerWindowTag; 34 | 35 | 36 | typedef NS_ENUM(NSInteger, MZFormSheetWhenKeyboardAppears) { 37 | MZFormSheetWhenKeyboardAppearsDoNothing = 0, 38 | MZFormSheetWhenKeyboardAppearsCenterVertically, 39 | MZFormSheetWhenKeyboardAppearsMoveToTop, 40 | MZFormSheetWhenKeyboardAppearsMoveToTopInset, 41 | MZFormSheetWhenKeyboardAppearsMoveAboveKeyboard 42 | }; 43 | 44 | /** 45 | Notifications are posted right after completion handlers 46 | 47 | @see willPresentCompletionHandler 48 | @see willDismissCompletionHandler 49 | @see didPresentCompletionHandler 50 | @see didDismissCompletionHandler 51 | */ 52 | extern NSString *const __nonnull MZFormSheetWillPresentNotification; 53 | extern NSString *const __nonnull MZFormSheetWillDismissNotification; 54 | extern NSString *const __nonnull MZFormSheetDidPresentNotification; 55 | extern NSString *const __nonnull MZFormSheetDidDismissNotification; 56 | 57 | @class MZFormSheetController; 58 | 59 | typedef void(^MZFormSheetCompletionHandler)(UIViewController * __nonnull presentedFSViewController); 60 | typedef void(^MZFormSheetBackgroundViewTapCompletionHandler)(CGPoint location); 61 | typedef void(^MZFormSheetPresentationCompletionHandler)(MZFormSheetController * __nonnull formSheetController); 62 | typedef void(^MZFormSheetTransitionCompletionHandler)(); 63 | 64 | @interface MZFormSheetWindow : UIWindow 65 | 66 | /** 67 | Returns whether the window should be touch transparent. 68 | If transparent is set to YES, window will not recive touch and didTapOnBackgroundViewCompletionHandler will not be called. 69 | Also will not be possible to dismiss form sheet on background tap. 70 | By default, this is NO. 71 | */ 72 | @property (nonatomic, assign, getter = isTransparentTouchEnabled) BOOL transparentTouchEnabled MZ_APPEARANCE_SELECTOR; 73 | @end 74 | 75 | @interface MZFormSheetController : UIViewController 76 | /** 77 | * Register custom transition animation style. 78 | * You need to setup transitionStyle to MZFormSheetTransitionStyleCustom. 79 | * 80 | * @param transitionClass Custom transition class. 81 | * @param transitionStyle The transition style to use when presenting the receiver. 82 | */ 83 | + (void)registerTransitionClass:(nonnull Class)transitionClass forTransitionStyle:(MZFormSheetTransitionStyle)transitionStyle; 84 | 85 | + (nullable Class)classForTransitionStyle:(MZFormSheetTransitionStyle)transitionStyle; 86 | 87 | /** 88 | Returns the background window that is displayed below form sheet controller. 89 | */ 90 | + (nonnull MZFormSheetBackgroundWindow *)sharedBackgroundWindow; 91 | 92 | /** 93 | Returns copy of formSheetController stack, last object in array (form sheet controller) is on top. 94 | */ 95 | + (nonnull NSArray *)formSheetControllersStack; 96 | 97 | /** 98 | Returns a boolean if it is animating. 99 | */ 100 | + (BOOL)isAnimating; 101 | 102 | /** 103 | Returns the window that form sheet controller is displayed . 104 | */ 105 | @property (nonatomic, readonly, strong, null_resettable) MZFormSheetWindow *formSheetWindow; 106 | 107 | /** 108 | The view controller that is presented by this form sheet controller. 109 | MZFormSheetController (self) --> presentedFSViewController 110 | */ 111 | @property (nonatomic, readonly, strong, nullable) UIViewController *presentedFSViewController; 112 | 113 | /** 114 | The view controller that is presenting this form sheet controller. 115 | This is only set up if you use UIViewController (MZFormSheet) category to present form sheet controller. 116 | presentingFSViewController --> MZFormSheetController (self) --> presentedFSViewController 117 | */ 118 | @property (nonatomic, readonly, weak, nullable) UIViewController *presentingFSViewController; 119 | 120 | /** 121 | The transition style to use when presenting the receiver. 122 | By default, this is MZFormSheetTransitionStyleSlideFromTop. 123 | */ 124 | @property (nonatomic, assign) MZFormSheetTransitionStyle transitionStyle MZ_APPEARANCE_SELECTOR; 125 | 126 | /** 127 | The handler to call when presented form sheet is before entry transition and its view will show on window. 128 | */ 129 | @property (nonatomic, copy, nullable) MZFormSheetCompletionHandler willPresentCompletionHandler; 130 | 131 | /** 132 | The handler to call when presented form sheet will be dismiss, this is called before out transition animation. 133 | */ 134 | @property (nonatomic, copy, nullable) MZFormSheetCompletionHandler willDismissCompletionHandler; 135 | 136 | /** 137 | The handler to call when presented form sheet is after entry transition animation. 138 | */ 139 | @property (nonatomic, copy, nullable) MZFormSheetCompletionHandler didPresentCompletionHandler; 140 | 141 | /** 142 | The handler to call when presented form sheet is after dismiss. 143 | */ 144 | @property (nonatomic, copy, nullable) MZFormSheetCompletionHandler didDismissCompletionHandler; 145 | 146 | /** 147 | The handler to call when user tap on background view. 148 | */ 149 | @property (nonatomic, copy, nullable) MZFormSheetBackgroundViewTapCompletionHandler didTapOnBackgroundViewCompletionHandler; 150 | 151 | /** 152 | Distance that the presented form sheet view is inset from the status bar in landscape orientation. 153 | By default, this is 6.0 154 | */ 155 | @property (nonatomic, assign) CGFloat landscapeTopInset MZ_APPEARANCE_SELECTOR; 156 | 157 | /** 158 | Distance that the presented form sheet view is inset from the status bar in portrait orientation. 159 | By default, this is 66.0 160 | */ 161 | @property (nonatomic, assign) CGFloat portraitTopInset MZ_APPEARANCE_SELECTOR; 162 | 163 | /** 164 | The radius to use when drawing rounded corners for the layer’s presented form sheet view background. 165 | By default, this is 6.0 166 | */ 167 | @property (nonatomic, assign) CGFloat cornerRadius MZ_APPEARANCE_SELECTOR; 168 | 169 | /** 170 | The blur radius (in points) used to render the layer’s shadow. 171 | By default, this is 6.0 172 | */ 173 | @property (nonatomic, assign) CGFloat shadowRadius MZ_APPEARANCE_SELECTOR; 174 | 175 | /** 176 | The opacity of the layer’s shadow. 177 | By default, this is 0.5 178 | */ 179 | @property (nonatomic, assign) CGFloat shadowOpacity MZ_APPEARANCE_SELECTOR; 180 | 181 | /** 182 | Size for presented form sheet controller 183 | By default, this is CGSizeMake(284.0,284.0) 184 | */ 185 | @property (nonatomic, assign) CGSize presentedFormSheetSize MZ_APPEARANCE_SELECTOR; 186 | 187 | /** 188 | Center form sheet vertically. 189 | By default, this is NO 190 | */ 191 | @property (nonatomic, assign) BOOL shouldCenterVertically MZ_APPEARANCE_SELECTOR; 192 | 193 | /** 194 | Returns whether the form sheet controller should dismiss after background view tap. 195 | By default, this is NO 196 | */ 197 | @property (nonatomic, assign) BOOL shouldDismissOnBackgroundViewTap MZ_APPEARANCE_SELECTOR; 198 | 199 | /** 200 | The movement style to use when the keyboard appears. 201 | By default, this is MZFormSheetWhenKeyboardAppearsMoveToTop. 202 | */ 203 | @property (nonatomic, assign) MZFormSheetWhenKeyboardAppears movementWhenKeyboardAppears MZ_APPEARANCE_SELECTOR; 204 | 205 | /** 206 | Initializes and returns a newly created form sheet controller. 207 | 208 | @param presentedFormSheetViewController The view controller that is presented by form sheet controller. 209 | */ 210 | - (nonnull instancetype)initWithViewController:(UIViewController * __nonnull )presentedFormSheetViewController; 211 | 212 | /** 213 | Initializes and returns a newly created form sheet controller. 214 | 215 | @param formSheetSize The size, in points, for the form sheet controller. 216 | @param presentedFormSheetViewController The view controller that is presented by form sheet controller. 217 | */ 218 | - (nonnull instancetype)initWithSize:(CGSize)formSheetSize viewController:(UIViewController * __nonnull )presentedFormSheetViewController; 219 | 220 | /** 221 | Presents a form sheet controller. 222 | 223 | @param animated Pass YES to animate the transition. 224 | @param completionHandler A completion handler (didPresentCompletionHandler) or NULL. 225 | */ 226 | - (void)presentAnimated:(BOOL)animated completionHandler:(MZFormSheetCompletionHandler __nullable)completionHandler; 227 | 228 | /** 229 | Dismisses a form sheet controller. 230 | 231 | @param animated Pass YES to animate the transition. 232 | @param completionHandler A completion handler (didDismissCompletionHandler) or NULL. 233 | */ 234 | - (void)dismissAnimated:(BOOL)animated completionHandler:(MZFormSheetCompletionHandler __nullable)completionHandler; 235 | 236 | @end 237 | 238 | /** 239 | Category on UIViewController to provide access to the formSheetController. 240 | */ 241 | @interface UIViewController (MZFormSheet) 242 | @property (nonatomic, readonly, nullable) MZFormSheetController *formSheetController; 243 | 244 | /** 245 | Presents a form sheet cotnroller 246 | @param formSheetController The form sheet controller or a subclass of MZFormSheetController. 247 | @param completionHandler A completion handler or NULL. 248 | */ 249 | - (void)mz_presentFormSheetController:(MZFormSheetController * __nonnull )formSheetController animated:(BOOL)animated completionHandler:(MZFormSheetPresentationCompletionHandler __nullable)completionHandler; 250 | 251 | /** 252 | Creates a new form sheet controller and presents it. 253 | 254 | @param viewController The view controller that is presented by form sheet controller. 255 | @param transitionStyle he transition style to use when presenting the receiver. 256 | @param completionHandler A completion handler or NULL. 257 | */ 258 | - (void)mz_presentFormSheetWithViewController:(UIViewController * __nonnull )viewController animated:(BOOL)animated transitionStyle:(MZFormSheetTransitionStyle)transitionStyle completionHandler:(MZFormSheetPresentationCompletionHandler __nullable)completionHandler; 259 | 260 | - (void)mz_presentFormSheetWithViewController:(UIViewController * __nonnull )viewController animated:(BOOL)animated completionHandler:(MZFormSheetPresentationCompletionHandler __nullable)completionHandler; 261 | 262 | /** 263 | Dismisses the form sheet controller that was presented by the receiver. If not find, last form sheet will be dismissed. 264 | @param animated Pass YES to animate the transition. 265 | @param completionHandler A completion handler (didDismissCompletionHandler) or NULL. 266 | */ 267 | - (void)mz_dismissFormSheetControllerAnimated:(BOOL)animated completionHandler:(MZFormSheetPresentationCompletionHandler __nullable)completionHandler; 268 | 269 | @end 270 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetSegue.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZFormSheetSegue.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 08.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | #import "MZFormSheetController.h" 28 | 29 | @interface MZFormSheetSegue : UIStoryboardSegue 30 | @property (nonatomic, strong, nonnull) MZFormSheetController *formSheetController; 31 | @end 32 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetSegue.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZFormSheetSegue.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 08.08.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "MZFormSheetSegue.h" 27 | #import "MZFormSheetController.h" 28 | 29 | @implementation MZFormSheetSegue 30 | 31 | - (id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination 32 | { 33 | if (self = [super initWithIdentifier:identifier source:source destination:destination]) { 34 | _formSheetController = [[MZFormSheetController alloc] initWithViewController:destination]; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)perform 40 | { 41 | UIViewController *sourceViewController = [self sourceViewController]; 42 | 43 | [sourceViewController mz_presentFormSheetController:self.formSheetController animated:YES completionHandler:nil]; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZTransition.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 21.12.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | extern NSString *const __nonnull MZTransitionExceptionMethodNotImplemented; 27 | 28 | typedef void(^MZTransitionCompletionHandler)(); 29 | 30 | @class MZFormSheetController; 31 | 32 | typedef NS_ENUM(NSInteger, MZFormSheetTransitionStyle) { 33 | MZFormSheetTransitionStyleSlideFromTop = 0, 34 | MZFormSheetTransitionStyleSlideFromBottom, 35 | MZFormSheetTransitionStyleSlideFromLeft, 36 | MZFormSheetTransitionStyleSlideFromRight, 37 | MZFormSheetTransitionStyleSlideAndBounceFromLeft, 38 | MZFormSheetTransitionStyleSlideAndBounceFromRight, 39 | MZFormSheetTransitionStyleFade, 40 | MZFormSheetTransitionStyleBounce, 41 | MZFormSheetTransitionStyleDropDown, 42 | MZFormSheetTransitionStyleCustom, 43 | MZFormSheetTransitionStyleNone, 44 | }; 45 | 46 | @protocol MZFormSheetControllerTransition 47 | @required 48 | /** 49 | Subclasses must implement to add custom transition animation. 50 | When animation is finished you must call super method or completionHandler to keep view life cycle. 51 | */ 52 | - (void)entryFormSheetControllerTransition:(nonnull UIViewController *)formSheetController completionHandler:(nonnull MZTransitionCompletionHandler)completionHandler; 53 | - (void)exitFormSheetControllerTransition:(nonnull UIViewController *)formSheetController completionHandler:(nonnull MZTransitionCompletionHandler)completionHandler; 54 | 55 | @end 56 | 57 | @interface MZFormSheetTransition : NSObject 58 | - (nonnull UIView *)contentViewControllerForController:(nonnull UIViewController *)viewController; 59 | @end 60 | -------------------------------------------------------------------------------- /MZFormSheetController/MZFormSheetTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZTransition.m 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 21.12.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "MZFormSheetTransition.h" 27 | #import "MZFormSheetController.h" 28 | 29 | NSString *const MZTransitionExceptionMethodNotImplemented = @"MZTransitionExceptionMethodNotImplemented"; 30 | 31 | CGFloat const MZTransitionDefaultBounceDuration = 0.4; 32 | CGFloat const MZTransitionDefaultDropDownDuration = 0.4; 33 | 34 | @implementation MZFormSheetTransition 35 | 36 | - (UIView *)contentViewControllerForController:(UIViewController *)viewController { 37 | return ((MZFormSheetController *)viewController).presentedFSViewController.view; 38 | } 39 | 40 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 41 | { 42 | [NSException raise:MZTransitionExceptionMethodNotImplemented format:@"-[%@ entryFormSheetControllerTransition:completionHandler:] must be implemented", NSStringFromClass([self class])]; 43 | } 44 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 45 | { 46 | [NSException raise:MZTransitionExceptionMethodNotImplemented format:@"-[%@ exitFormSheetControllerTransition:completionHandler:] must be implemented", NSStringFromClass([self class])]; 47 | } 48 | 49 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 50 | { 51 | void(^completionHandler)(void) = [anim valueForKey:@"completionHandler"]; 52 | if (completionHandler) { 53 | completionHandler(); 54 | } 55 | } 56 | 57 | @end 58 | 59 | @interface MZSlideFromTopTransition : MZFormSheetTransition 60 | @end 61 | 62 | @implementation MZSlideFromTopTransition 63 | + (void)load 64 | { 65 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleSlideFromTop]; 66 | } 67 | 68 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 69 | { 70 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 71 | CGRect originalFormSheetRect = formSheetRect; 72 | formSheetRect.origin.y = -formSheetRect.size.height; 73 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 74 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 75 | animations:^{ 76 | [self contentViewControllerForController:formSheetController].frame = originalFormSheetRect; 77 | } 78 | completion:^(BOOL finished) { 79 | completionHandler(); 80 | }]; 81 | } 82 | 83 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 84 | { 85 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 86 | formSheetRect.origin.y = -formSheetController.view.bounds.size.height; 87 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 88 | animations:^{ 89 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 90 | } 91 | completion:^(BOOL finished) { 92 | completionHandler(); 93 | }]; 94 | } 95 | @end 96 | 97 | @interface MZSlideFromBottomTransition : MZFormSheetTransition 98 | @end 99 | 100 | @implementation MZSlideFromBottomTransition 101 | + (void)load 102 | { 103 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleSlideFromBottom]; 104 | } 105 | 106 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 107 | { 108 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 109 | CGRect originalFormSheetRect = formSheetRect; 110 | formSheetRect.origin.y = formSheetController.view.bounds.size.height; 111 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 112 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 113 | animations:^{ 114 | [self contentViewControllerForController:formSheetController].frame = originalFormSheetRect; 115 | } 116 | completion:^(BOOL finished) { 117 | completionHandler(); 118 | }]; 119 | } 120 | 121 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 122 | { 123 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 124 | formSheetRect.origin.y = formSheetController.view.bounds.size.height; 125 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 126 | delay:0 127 | options:UIViewAnimationOptionCurveEaseIn 128 | animations:^{ 129 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 130 | } 131 | completion:^(BOOL finished) { 132 | completionHandler(); 133 | }]; 134 | } 135 | @end 136 | 137 | @interface MZSlideFromLeftTransition : MZFormSheetTransition 138 | @end 139 | 140 | @implementation MZSlideFromLeftTransition 141 | + (void)load 142 | { 143 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleSlideFromLeft]; 144 | } 145 | 146 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 147 | { 148 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 149 | CGRect originalFormSheetRect = formSheetRect; 150 | formSheetRect.origin.x = -formSheetController.view.bounds.size.width; 151 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 152 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 153 | animations:^{ 154 | [self contentViewControllerForController:formSheetController].frame = originalFormSheetRect; 155 | } 156 | completion:^(BOOL finished) { 157 | completionHandler(); 158 | }]; 159 | } 160 | 161 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 162 | { 163 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 164 | formSheetRect.origin.x = -formSheetController.view.bounds.size.width; 165 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 166 | animations:^{ 167 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 168 | } 169 | completion:^(BOOL finished) { 170 | completionHandler(); 171 | }]; 172 | } 173 | @end 174 | 175 | @interface MZSlideFromRightTransition : MZFormSheetTransition 176 | @end 177 | 178 | @implementation MZSlideFromRightTransition 179 | + (void)load 180 | { 181 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleSlideFromRight]; 182 | } 183 | 184 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 185 | { 186 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 187 | CGRect originalFormSheetRect = formSheetRect; 188 | formSheetRect.origin.x = formSheetController.view.bounds.size.width; 189 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 190 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 191 | animations:^{ 192 | [self contentViewControllerForController:formSheetController].frame = originalFormSheetRect; 193 | } 194 | completion:^(BOOL finished) { 195 | completionHandler(); 196 | }]; 197 | } 198 | 199 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 200 | { 201 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 202 | formSheetRect.origin.x = formSheetController.view.bounds.size.width; 203 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 204 | animations:^{ 205 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 206 | } 207 | completion:^(BOOL finished) { 208 | completionHandler(); 209 | }]; 210 | } 211 | @end 212 | 213 | @interface MZSlideBounceFromLeftTransition : MZFormSheetTransition 214 | @end 215 | 216 | @implementation MZSlideBounceFromLeftTransition 217 | + (void)load 218 | { 219 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleSlideAndBounceFromLeft]; 220 | } 221 | 222 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 223 | { 224 | CGFloat x = [self contentViewControllerForController:formSheetController].center.x; 225 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"]; 226 | animation.values = @[@(x - formSheetController.view.bounds.size.width), @(x + 20), @(x - 10), @(x)]; 227 | animation.keyTimes = @[@(0), @(0.5), @(0.75), @(1)]; 228 | animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; 229 | animation.duration = MZTransitionDefaultDropDownDuration; 230 | animation.delegate = self; 231 | [animation setValue:completionHandler forKey:@"completionHandler"]; 232 | [[self contentViewControllerForController:formSheetController].layer addAnimation:animation forKey:@"bounceLeft"]; 233 | } 234 | 235 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 236 | { 237 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 238 | formSheetRect.origin.x = -formSheetController.view.bounds.size.width; 239 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 240 | animations:^{ 241 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 242 | } 243 | completion:^(BOOL finished) { 244 | completionHandler(); 245 | }]; 246 | } 247 | @end 248 | 249 | @interface MZSlideBounceFromRightTransition : MZFormSheetTransition 250 | @end 251 | 252 | @implementation MZSlideBounceFromRightTransition 253 | + (void)load 254 | { 255 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleSlideAndBounceFromRight]; 256 | } 257 | 258 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 259 | { 260 | CGFloat x = [self contentViewControllerForController:formSheetController].center.x; 261 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"]; 262 | animation.values = @[@(x + formSheetController.view.bounds.size.width), @(x - 20), @(x + 10), @(x)]; 263 | animation.keyTimes = @[@(0), @(0.5), @(0.75), @(1)]; 264 | animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; 265 | animation.duration = MZTransitionDefaultBounceDuration; 266 | animation.delegate = self; 267 | [animation setValue:completionHandler forKey:@"completionHandler"]; 268 | [[self contentViewControllerForController:formSheetController].layer addAnimation:animation forKey:@"bounceRight"]; 269 | } 270 | 271 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 272 | { 273 | CGRect formSheetRect = [self contentViewControllerForController:formSheetController].frame; 274 | formSheetRect.origin.x = formSheetController.view.bounds.size.width; 275 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 276 | animations:^{ 277 | [self contentViewControllerForController:formSheetController].frame = formSheetRect; 278 | } 279 | completion:^(BOOL finished) { 280 | completionHandler(); 281 | }]; 282 | } 283 | @end 284 | 285 | @interface MZFadeTransition : MZFormSheetTransition 286 | @end 287 | 288 | @implementation MZFadeTransition 289 | + (void)load 290 | { 291 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleFade]; 292 | } 293 | 294 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 295 | { 296 | [self contentViewControllerForController:formSheetController].alpha = 0; 297 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 298 | animations:^{ 299 | [self contentViewControllerForController:formSheetController].alpha = 1; 300 | } 301 | completion:^(BOOL finished) { 302 | completionHandler(); 303 | }]; 304 | } 305 | 306 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 307 | { 308 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 309 | animations:^{ 310 | [self contentViewControllerForController:formSheetController].alpha = 0; 311 | } 312 | completion:^(BOOL finished) { 313 | completionHandler(); 314 | }]; 315 | } 316 | @end 317 | 318 | @interface MZBounceTransition : MZFormSheetTransition 319 | @end 320 | 321 | @implementation MZBounceTransition 322 | + (void)load 323 | { 324 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleBounce]; 325 | } 326 | 327 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 328 | { 329 | CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; 330 | bounceAnimation.fillMode = kCAFillModeBoth; 331 | bounceAnimation.duration = MZTransitionDefaultBounceDuration; 332 | bounceAnimation.removedOnCompletion = YES; 333 | bounceAnimation.values = @[ 334 | [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.01f, 0.01f, 0.01f)], 335 | [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.1f)], 336 | [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9f, 0.9f, 0.9f)], 337 | [NSValue valueWithCATransform3D:CATransform3DIdentity]]; 338 | bounceAnimation.keyTimes = @[@0.0f, @0.5f, @0.75f, @1.0f]; 339 | bounceAnimation.timingFunctions = @[ 340 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], 341 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], 342 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 343 | bounceAnimation.delegate = self; 344 | [bounceAnimation setValue:completionHandler forKey:@"completionHandler"]; 345 | [[self contentViewControllerForController:formSheetController].layer addAnimation:bounceAnimation forKey:@"bounce"]; 346 | } 347 | 348 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 349 | { 350 | [self contentViewControllerForController:formSheetController].transform = CGAffineTransformMakeScale(0.01, 0.01); 351 | 352 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; 353 | animation.values = @[@(1), @(1.2), @(0.01)]; 354 | animation.keyTimes = @[@(0), @(0.4), @(1)]; 355 | animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; 356 | animation.duration = MZFormSheetControllerDefaultAnimationDuration; 357 | animation.removedOnCompletion = YES; 358 | animation.delegate = self; 359 | [animation setValue:completionHandler forKey:@"completionHandler"]; 360 | [[self contentViewControllerForController:formSheetController].layer addAnimation:animation forKey:@"bounce"]; 361 | 362 | [self contentViewControllerForController:formSheetController].transform = CGAffineTransformMakeScale(0.01, 0.01); 363 | } 364 | @end 365 | 366 | @interface MZDropDownTransition : MZFormSheetTransition 367 | @end 368 | 369 | @implementation MZDropDownTransition 370 | + (void)load 371 | { 372 | [MZFormSheetController registerTransitionClass:self forTransitionStyle:MZFormSheetTransitionStyleDropDown]; 373 | } 374 | 375 | - (void)entryFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 376 | { 377 | CGFloat y = [self contentViewControllerForController:formSheetController].center.y; 378 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.y"]; 379 | animation.values = @[@(y - formSheetController.view.bounds.size.height), @(y + 20), @(y - 10), @(y)]; 380 | animation.keyTimes = @[@(0), @(0.5), @(0.75), @(1)]; 381 | animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; 382 | animation.duration = MZTransitionDefaultDropDownDuration; 383 | animation.delegate = self; 384 | [animation setValue:completionHandler forKey:@"completionHandler"]; 385 | [[self contentViewControllerForController:formSheetController].layer addAnimation:animation forKey:@"dropdown"]; 386 | } 387 | 388 | - (void)exitFormSheetControllerTransition:(MZFormSheetController *)formSheetController completionHandler:(MZTransitionCompletionHandler)completionHandler 389 | { 390 | CGPoint point = [self contentViewControllerForController:formSheetController].center; 391 | point.y += formSheetController.view.bounds.size.height; 392 | [UIView animateWithDuration:MZFormSheetControllerDefaultAnimationDuration 393 | delay:0 394 | options:UIViewAnimationOptionCurveEaseIn 395 | animations:^{ 396 | [self contentViewControllerForController:formSheetController].center = point; 397 | CGFloat angle = ((CGFloat)arc4random_uniform(100) - 50.f) / 100.f; 398 | [self contentViewControllerForController:formSheetController].transform = CGAffineTransformMakeRotation(angle); 399 | } 400 | completion:^(BOOL finished) { 401 | completionHandler(); 402 | }]; 403 | } 404 | @end -------------------------------------------------------------------------------- /MZFormSheetController/MZMacro.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZMacro.h 3 | // Xcode5Example 4 | // 5 | // Created by Michał Zaborowski on 28.08.2014. 6 | // Copyright (c) 2014 Michał Zaborowski. All rights reserved. 7 | // 8 | 9 | #if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) 10 | #define MZ_DEPRECATED_ATTRIBUTE(message) __attribute__((deprecated(message))) 11 | #else 12 | #define MZ_DEPRECATED_ATTRIBUTE(message) 13 | #endif 14 | 15 | #ifndef kCFCoreFoundationVersionNumber_iOS_7_0 16 | #define kCFCoreFoundationVersionNumber_iOS_7_0 847.2 17 | #endif 18 | 19 | #ifndef kCFCoreFoundationVersionNumber_iOS_8_0 20 | #define kCFCoreFoundationVersionNumber_iOS_8_0 1129.15 21 | #endif 22 | 23 | #ifndef kCFCoreFoundationVersionNumber_iOS_8_2 24 | #define kCFCoreFoundationVersionNumber_iOS_8_2 1142.16 25 | #endif 26 | 27 | #ifndef kCFCoreFoundationVersionNumber_iOS_9_0 28 | #define kCFCoreFoundationVersionNumber_iOS_9_0 1240.1 29 | #endif 30 | 31 | #define MZSystemVersionGreaterThanOrEqualTo_iOS7() (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) 32 | #define MZSystemVersionGreaterThanOrEqualTo_iOS8() (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) 33 | #define MZSystemVersionGreaterThanOrEqualTo_iOS9() (kCFCoreFoundationVersionNumber > kCFCoreFoundationVersionNumber_iOS_8_2) 34 | #define MZSystemVersionLessThan_iOS8() !MZSystemVersionGreaterThanOrEqualTo_iOS8() 35 | -------------------------------------------------------------------------------- /MZFormSheetController/UIImage+Additional.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Additional.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 05.09.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | 28 | @interface UIImage (Additional) 29 | 30 | - (nonnull UIImage *)imageRotatedByRadians:(CGFloat)radians; 31 | - (nonnull UIImage *)imageRotatedByDegrees:(CGFloat)degrees; 32 | 33 | - (nonnull UIImage *)blurredImageWithRadius:(CGFloat)blurRadius 34 | tintColor:(nullable UIColor *)tintColor 35 | saturationDeltaFactor:(CGFloat)saturationDeltaFactor 36 | maskImage:(nullable UIImage *)maskImage; 37 | @end 38 | -------------------------------------------------------------------------------- /MZFormSheetController/UIImage+Additional.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Additional.m 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 05.09.2013. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "UIImage+Additional.h" 27 | #import 28 | 29 | static CGFloat const degreesToRadians(CGFloat degrees) { 30 | return degrees * M_PI / 180; 31 | } 32 | 33 | static CGFloat const radiansToDegrees(CGFloat radians) { 34 | return radians * 180/M_PI; 35 | } 36 | 37 | @implementation UIImage (Additional) 38 | 39 | - (UIImage *)imageRotatedByRadians:(CGFloat)radians 40 | { 41 | return [self imageRotatedByDegrees:radiansToDegrees(radians)]; 42 | } 43 | 44 | - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees 45 | { 46 | // calculate the size of the rotated view's containing box for our drawing space 47 | UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)]; 48 | CGAffineTransform t = CGAffineTransformMakeRotation(degreesToRadians(degrees)); 49 | rotatedViewBox.transform = t; 50 | CGSize rotatedSize = rotatedViewBox.frame.size; 51 | 52 | // Create the bitmap context 53 | UIGraphicsBeginImageContext(rotatedSize); 54 | CGContextRef bitmap = UIGraphicsGetCurrentContext(); 55 | 56 | // Move the origin to the middle of the image so we will rotate and scale around the center. 57 | CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2); 58 | 59 | // Rotate the image context 60 | CGContextRotateCTM(bitmap, degreesToRadians(degrees)); 61 | 62 | // Now, draw the rotated/scaled image into the context 63 | CGContextScaleCTM(bitmap, 1.0, -1.0); 64 | CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]); 65 | 66 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 67 | UIGraphicsEndImageContext(); 68 | return newImage; 69 | } 70 | 71 | - (UIImage *)blurredImageWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage 72 | { 73 | // Check pre-conditions. 74 | if (self.size.width < 1 || self.size.height < 1) { 75 | NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self); 76 | return nil; 77 | } 78 | if (!self.CGImage) { 79 | NSLog (@"*** error: image must be backed by a CGImage: %@", self); 80 | return nil; 81 | } 82 | if (maskImage && !maskImage.CGImage) { 83 | NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage); 84 | return nil; 85 | } 86 | 87 | CGRect imageRect = { CGPointZero, self.size }; 88 | UIImage *effectImage = self; 89 | 90 | BOOL hasBlur = blurRadius > __FLT_EPSILON__; 91 | BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__; 92 | if (hasBlur || hasSaturationChange) { 93 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 94 | CGContextRef effectInContext = UIGraphicsGetCurrentContext(); 95 | CGContextScaleCTM(effectInContext, 1.0, -1.0); 96 | CGContextTranslateCTM(effectInContext, 0, -self.size.height); 97 | CGContextDrawImage(effectInContext, imageRect, self.CGImage); 98 | 99 | vImage_Buffer effectInBuffer; 100 | effectInBuffer.data = CGBitmapContextGetData(effectInContext); 101 | effectInBuffer.width = CGBitmapContextGetWidth(effectInContext); 102 | effectInBuffer.height = CGBitmapContextGetHeight(effectInContext); 103 | effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext); 104 | 105 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 106 | CGContextRef effectOutContext = UIGraphicsGetCurrentContext(); 107 | vImage_Buffer effectOutBuffer; 108 | effectOutBuffer.data = CGBitmapContextGetData(effectOutContext); 109 | effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext); 110 | effectOutBuffer.height = CGBitmapContextGetHeight(effectOutContext); 111 | effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext); 112 | 113 | if (hasBlur) { 114 | // A description of how to compute the box kernel width from the Gaussian 115 | // radius (aka standard deviation) appears in the SVG spec: 116 | // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement 117 | // 118 | // For larger values of 's' (s >= 2.0), an approximation can be used: Three 119 | // successive box-blurs build a piece-wise quadratic convolution kernel, which 120 | // approximates the Gaussian kernel to within roughly 3%. 121 | // 122 | // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5) 123 | // 124 | // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel. 125 | // 126 | CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale]; 127 | uint32_t radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5); 128 | if (radius % 2 != 1) { 129 | radius += 1; // force radius to be odd so that the three box-blur methodology works. 130 | } 131 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 132 | vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 133 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 134 | } 135 | BOOL effectImageBuffersAreSwapped = NO; 136 | if (hasSaturationChange) { 137 | CGFloat s = saturationDeltaFactor; 138 | CGFloat floatingPointSaturationMatrix[] = { 139 | 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0, 140 | 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0, 141 | 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0, 142 | 0, 0, 0, 1, 143 | }; 144 | const int32_t divisor = 256; 145 | NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]); 146 | int16_t saturationMatrix[matrixSize]; 147 | for (NSUInteger i = 0; i < matrixSize; ++i) { 148 | saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor); 149 | } 150 | if (hasBlur) { 151 | vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 152 | effectImageBuffersAreSwapped = YES; 153 | } 154 | else { 155 | vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 156 | } 157 | } 158 | if (!effectImageBuffersAreSwapped) 159 | effectImage = UIGraphicsGetImageFromCurrentImageContext(); 160 | UIGraphicsEndImageContext(); 161 | 162 | if (effectImageBuffersAreSwapped) 163 | effectImage = UIGraphicsGetImageFromCurrentImageContext(); 164 | UIGraphicsEndImageContext(); 165 | } 166 | 167 | // Set up output context. 168 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 169 | CGContextRef outputContext = UIGraphicsGetCurrentContext(); 170 | CGContextScaleCTM(outputContext, 1.0, -1.0); 171 | CGContextTranslateCTM(outputContext, 0, -self.size.height); 172 | 173 | // Draw base image. 174 | CGContextDrawImage(outputContext, imageRect, self.CGImage); 175 | 176 | // Draw effect image. 177 | if (hasBlur) { 178 | CGContextSaveGState(outputContext); 179 | if (maskImage) { 180 | CGContextClipToMask(outputContext, imageRect, maskImage.CGImage); 181 | } 182 | CGContextDrawImage(outputContext, imageRect, effectImage.CGImage); 183 | CGContextRestoreGState(outputContext); 184 | } 185 | 186 | // Add in color tint. 187 | if (tintColor) { 188 | CGContextSaveGState(outputContext); 189 | CGContextSetFillColorWithColor(outputContext, tintColor.CGColor); 190 | CGContextFillRect(outputContext, imageRect); 191 | CGContextRestoreGState(outputContext); 192 | } 193 | 194 | // Output image is ready. 195 | UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); 196 | UIGraphicsEndImageContext(); 197 | 198 | return outputImage; 199 | } 200 | 201 | @end 202 | -------------------------------------------------------------------------------- /MZFormSheetController/UIViewController+TargetViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+TargetViewController.h 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 16.01.2014. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | 28 | @interface UIViewController (MZFormSheetTargetViewController) 29 | 30 | - (nullable UIViewController *)mz_parentTargetViewController; 31 | - (nullable UIViewController *)mz_childTargetViewControllerForStatusBarStyle; 32 | - (nullable UIViewController *)mz_childTargetViewControllerForStatusBarHidden; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /MZFormSheetController/UIViewController+TargetViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+TargetViewController.m 3 | // MZFormSheetController 4 | // 5 | // Created by Michał Zaborowski on 16.01.2014. 6 | // Copyright (c) 2013 Michał Zaborowski. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all 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, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "UIViewController+TargetViewController.h" 27 | 28 | @implementation UIViewController (MZFormSheetTargetViewController) 29 | 30 | - (UIViewController *)mz_parentTargetViewController 31 | { 32 | UIViewController *parentTargetViewController = self; 33 | while (parentTargetViewController.presentedViewController) { 34 | parentTargetViewController = parentTargetViewController.presentedViewController; 35 | } 36 | return parentTargetViewController; 37 | } 38 | 39 | - (UIViewController *)mz_childTargetViewControllerForStatusBarStyle 40 | { 41 | UIViewController *childTargetViewController; 42 | 43 | if ([self respondsToSelector:@selector(childViewControllerForStatusBarStyle)]) { 44 | childTargetViewController = [self childViewControllerForStatusBarStyle]; 45 | if (childTargetViewController) { 46 | return [childTargetViewController mz_childTargetViewControllerForStatusBarStyle]; 47 | } 48 | } 49 | 50 | return self; 51 | } 52 | 53 | - (UIViewController *)mz_childTargetViewControllerForStatusBarHidden 54 | { 55 | UIViewController *childTargetViewController; 56 | 57 | if ([self respondsToSelector:@selector(childViewControllerForStatusBarHidden)]) { 58 | childTargetViewController = [self childViewControllerForStatusBarHidden]; 59 | if (childTargetViewController) { 60 | return [childTargetViewController mz_childTargetViewControllerForStatusBarHidden]; 61 | } 62 | } 63 | 64 | return self; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Screens/animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Screens/animation.gif -------------------------------------------------------------------------------- /Screens/animation1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Screens/animation1.gif -------------------------------------------------------------------------------- /Screens/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Screens/screen1.png -------------------------------------------------------------------------------- /Screens/screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Screens/screen2.png -------------------------------------------------------------------------------- /Screens/screen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m1entus/MZFormSheetController/7777bc78f182aa572bc423987fca21eb5fbfea50/Screens/screen3.png --------------------------------------------------------------------------------