├── .gitignore ├── LICENSE ├── MaskZoomTransition.gif ├── MaskZoomTransition.podspec ├── MaskZoomTransition ├── MZGradientCircleLayer.h ├── MZGradientCircleLayer.m ├── MZMaskZoomTransition.h ├── MZMaskZoomTransition.m ├── MZMaskZoomTransitioningDelegate.h ├── MZMaskZoomTransitioningDelegate.m ├── UIViewController+MZContentViewController.h └── UIViewController+MZContentViewController.m ├── MaskZoomTransitionDemo.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ └── MaskZoomTransitionDemo.xcscheme ├── MaskZoomTransitionDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── app-icon-29.png │ │ ├── app-icon-29@2x-1.png │ │ ├── app-icon-29@2x.png │ │ ├── app-icon-29@3x.png │ │ ├── app-icon-40.png │ │ ├── app-icon-40@2x-1.png │ │ ├── app-icon-40@2x.png │ │ ├── app-icon-40@3x.png │ │ ├── app-icon-60@2x.png │ │ ├── app-icon-60@3x.png │ │ ├── app-icon-76.png │ │ ├── app-icon-76@2x.png │ │ └── app-icon-83.5@2x.png │ ├── Contents.json │ ├── People │ │ ├── Contents.json │ │ ├── amelia-walker.imageset │ │ │ ├── Contents.json │ │ │ ├── amelia-walker.png │ │ │ └── amelia-walker@2x.png │ │ ├── diane-howell.imageset │ │ │ ├── Contents.json │ │ │ ├── diane-howell.png │ │ │ └── diane-howell@2x.png │ │ ├── george-shelton.imageset │ │ │ ├── Contents.json │ │ │ ├── george-shelton.png │ │ │ └── george-shelton@2x.png │ │ ├── julia-allen.imageset │ │ │ ├── Contents.json │ │ │ ├── julia-allen.png │ │ │ └── julia-allen@2x.png │ │ ├── lauren-king.imageset │ │ │ ├── Contents.json │ │ │ ├── lauren-king.png │ │ │ └── lauren-king@2x.png │ │ ├── maria-garrett.imageset │ │ │ ├── Contents.json │ │ │ ├── maria-garrett.png │ │ │ └── maria-garrett@2x.png │ │ ├── matthew-fuller.imageset │ │ │ ├── Contents.json │ │ │ ├── matthew-fuller.png │ │ │ └── matthew-fuller@2x.png │ │ ├── nicholas-palmer.imageset │ │ │ ├── Contents.json │ │ │ ├── nicholas-palmer.png │ │ │ └── nicholas-palmer@2x.png │ │ ├── stephanie-sharp.imageset │ │ │ ├── Contents.json │ │ │ ├── stephanie-sharp.png │ │ │ ├── stephanie-sharp@2x.png │ │ │ └── stephanie-sharp@3x.png │ │ ├── thomas-lynch.imageset │ │ │ ├── Contents.json │ │ │ ├── thomas-lynch.png │ │ │ └── thomas-lynch@2x.png │ │ └── vincent-greene.imageset │ │ │ ├── Contents.json │ │ │ ├── vincent-greene.png │ │ │ └── vincent-greene@2x.png │ ├── Profile │ │ ├── Contents.json │ │ ├── address-book-filled.imageset │ │ │ ├── Contents.json │ │ │ ├── address-book-filled.png │ │ │ ├── address-book-filled@2x.png │ │ │ └── address-book-filled@3x.png │ │ ├── address-book.imageset │ │ │ ├── Contents.json │ │ │ ├── address-book.png │ │ │ ├── address-book@2x.png │ │ │ └── address-book@3x.png │ │ ├── exit-filled.imageset │ │ │ ├── Contents.json │ │ │ ├── exit-filled.png │ │ │ ├── exit-filled@2x.png │ │ │ └── exit-filled@3x.png │ │ ├── exit.imageset │ │ │ ├── Contents.json │ │ │ ├── exit.png │ │ │ ├── exit@2x.png │ │ │ └── exit@3x.png │ │ ├── left-arrow.imageset │ │ │ ├── Contents.json │ │ │ ├── left-arrow.png │ │ │ ├── left-arrow@2x.png │ │ │ └── left-arrow@3x.png │ │ ├── mail-filled.imageset │ │ │ ├── Contents.json │ │ │ ├── mail-filled.png │ │ │ ├── mail-filled@2x.png │ │ │ └── mail-filled@3x.png │ │ ├── mail.imageset │ │ │ ├── Contents.json │ │ │ ├── mail.png │ │ │ ├── mail@2x.png │ │ │ └── mail@3x.png │ │ ├── message-filled.imageset │ │ │ ├── Contents.json │ │ │ ├── message-filled.png │ │ │ ├── message-filled@2x.png │ │ │ └── message-filled@3x.png │ │ ├── message.imageset │ │ │ ├── Contents.json │ │ │ ├── message.png │ │ │ ├── message@2x.png │ │ │ └── message@3x.png │ │ ├── phone-filled.imageset │ │ │ ├── Contents.json │ │ │ ├── phone-filled.png │ │ │ ├── phone-filled@2x.png │ │ │ └── phone-filled@3x.png │ │ ├── phone.imageset │ │ │ ├── Contents.json │ │ │ ├── phone.png │ │ │ ├── phone@2x.png │ │ │ └── phone@3x.png │ │ ├── star-filled.imageset │ │ │ ├── Contents.json │ │ │ ├── star-filled.png │ │ │ ├── star-filled@2x.png │ │ │ └── star-filled@3x.png │ │ ├── star.imageset │ │ │ ├── Contents.json │ │ │ ├── star.png │ │ │ ├── star@2x.png │ │ │ └── star@3x.png │ │ ├── stars-filled.imageset │ │ │ ├── Contents.json │ │ │ ├── stars-filled.png │ │ │ ├── stars-filled@2x.png │ │ │ └── stars-filled@3x.png │ │ └── stars.imageset │ │ │ ├── Contents.json │ │ │ ├── stars.png │ │ │ ├── stars@2x.png │ │ │ └── stars@3x.png │ └── launch-screen.imageset │ │ ├── Contents.json │ │ ├── launch-screen.png │ │ ├── launch-screen@2x.png │ │ └── launch-screen@3x.png ├── Base.lproj │ ├── Colors.storyboard │ ├── LaunchScreen.storyboard │ ├── Main.storyboard │ └── People.storyboard ├── Categories │ ├── Navigation │ │ ├── UIView+MZNavigationBar.h │ │ └── UIView+MZNavigationBar.m │ └── View Containment │ │ ├── UIView+MZEmbed.h │ │ └── UIView+MZEmbed.m ├── Colors │ ├── View Controllers │ │ ├── MZColorViewController.h │ │ ├── MZColorViewController.m │ │ ├── MZColorsViewController.h │ │ └── MZColorsViewController.m │ └── Views │ │ ├── MZCircleButton.h │ │ ├── MZCircleButton.m │ │ ├── MZCircleView.h │ │ └── MZCircleView.m ├── Info.plist ├── People │ ├── Controllers │ │ ├── MZProfilesController.h │ │ └── MZProfilesController.m │ ├── Data Store │ │ ├── MZPeople.plist │ │ ├── MZPersonStore.h │ │ └── MZPersonStore.m │ ├── Models │ │ ├── MZPerson.h │ │ ├── MZPerson.m │ │ ├── MZProfile.h │ │ ├── MZProfile.m │ │ ├── NSString+MZProfile.h │ │ └── NSString+MZProfile.m │ ├── View Controllers │ │ ├── MZPeopleTableViewController.h │ │ ├── MZPeopleTableViewController.m │ │ ├── MZProfileViewController.h │ │ └── MZProfileViewController.m │ └── Views │ │ ├── MZCircleImageView.h │ │ ├── MZCircleImageView.m │ │ ├── MZLineView.h │ │ ├── MZLineView.m │ │ ├── MZPersonCell.h │ │ ├── MZPersonCell.m │ │ ├── MZProfileButton.h │ │ ├── MZProfileButton.m │ │ ├── MZProfileCell.h │ │ ├── MZProfileCell.m │ │ ├── MZTopImageButton.h │ │ └── MZTopImageButton.m ├── Theme │ ├── MZTheme.h │ ├── MZTheme.m │ ├── UIColor+MZTheme.h │ └── UIColor+MZTheme.m └── main.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X 2 | *.DS_Store 3 | 4 | # Xcode 5 | *.pbxuser 6 | *.mode1v3 7 | *.mode2v3 8 | *.perspectivev3 9 | *.xcuserstate 10 | project.xcworkspace/ 11 | xcuserdata/ 12 | 13 | # Generated files 14 | *.o 15 | *.pyc 16 | 17 | #Python modules 18 | MANIFEST 19 | dist/ 20 | build/ 21 | 22 | # Backup files 23 | *~.nib 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Stephanie Sharp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MaskZoomTransition.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransition.gif -------------------------------------------------------------------------------- /MaskZoomTransition.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "MaskZoomTransition" 3 | s.version = "0.1" 4 | s.summary = "A Material Design-inspired transition." 5 | s.homepage = "https://github.com/stephsharp/MaskZoomTransition" 6 | s.license = { :type => "MIT", :file => "LICENSE" } 7 | s.author = "Stephanie Sharp" 8 | s.platform = :ios, "9.0" 9 | s.source = { :git => "https://github.com/stephsharp/MaskZoomTransition.git", :tag => "v#{s.version}" } 10 | s.source_files = "MaskZoomTransition" 11 | s.public_header_files = [ "MaskZoomTransition/MZMaskZoomTransition.h", 12 | "MaskZoomTransition/MZMaskZoomTransitioningDelegate.h", 13 | "MaskZoomTransition/UIViewController+MZContentViewController.h" ] 14 | s.requires_arc = true 15 | end 16 | -------------------------------------------------------------------------------- /MaskZoomTransition/MZGradientCircleLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZGradientCircleLayer.h 3 | // MaskZoomTransition 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZGradientCircleLayer : CALayer 12 | 13 | @property (nonatomic) CGFloat gradientWidth; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /MaskZoomTransition/MZGradientCircleLayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZGradientCircleLayer.m 3 | // MaskZoomTransition 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZGradientCircleLayer.h" 10 | 11 | @implementation MZGradientCircleLayer 12 | 13 | - (void)drawInContext:(CGContextRef)context 14 | { 15 | CGPoint origin = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); 16 | CGFloat gradientRadius = CGRectGetWidth(self.bounds) / 2.0f; 17 | CGFloat innerCircleRadius = gradientRadius - self.gradientWidth; 18 | 19 | CGColorSpaceRef baseColorSpace = CGColorSpaceCreateDeviceRGB(); 20 | CGFloat colors[8] = { 0.0f, 0.0f, 0.0f, 1.0f, 21 | 0.0f, 0.0f, 0.0f, 0.0f 22 | }; 23 | CGFloat colorLocations[2] = { 0.0f, 1.0f }; 24 | CGGradientRef gradient = CGGradientCreateWithColorComponents(baseColorSpace, colors, colorLocations, 2); 25 | 26 | CGContextDrawRadialGradient(context, gradient, origin, innerCircleRadius, origin, gradientRadius, kCGGradientDrawsBeforeStartLocation); 27 | 28 | CGColorSpaceRelease(baseColorSpace); 29 | CGGradientRelease(gradient); 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /MaskZoomTransition/MZMaskZoomTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZMaskZoomTransition.h 3 | // MaskZoomTransition 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZMaskZoomTransition : NSObject 12 | 13 | /** 14 | * Small view to transition from. 15 | */ 16 | @property (nonatomic) UIView *smallView; 17 | 18 | /** 19 | * Large view to transition to. 20 | */ 21 | @property (nonatomic) UIView *largeView; 22 | 23 | /** 24 | * Views to fade in at the end of the transition. 25 | */ 26 | @property (nonatomic) NSArray *viewsToFadeIn; 27 | 28 | /** 29 | * Default is 0.25 seconds. 30 | */ 31 | @property (nonatomic) NSTimeInterval duration; 32 | 33 | /** 34 | * Default is YES. Set to NO when dismissing a view controller. 35 | */ 36 | @property (nonatomic) BOOL presenting; 37 | 38 | /** 39 | * Default is NO. Set to YES if you want the dismiss transition to shrink the view down to zero. 40 | * This is useful if the smallView in the presentingViewController is no longer visible. 41 | */ 42 | @property (nonatomic) BOOL dismissToZeroSize; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /MaskZoomTransition/MZMaskZoomTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZMaskZoomTransition.m 3 | // MaskZoomTransition 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZMaskZoomTransition.h" 10 | #import "MZGradientCircleLayer.h" 11 | 12 | @interface MZMaskZoomTransition () 13 | 14 | @property (nonatomic) id transitionContext; 15 | @property (nonatomic) UIViewController *toViewController; 16 | @property (nonatomic) UIViewController *fromViewController; 17 | @property (nonatomic) UIView *containerView; 18 | @property (nonatomic) UIView *toView; 19 | @property (nonatomic) UIView *fromView; 20 | @property (nonatomic) UIView *maskView; 21 | @property (nonatomic) UIView *shadowView; 22 | @property (nonatomic) UIView *largeViewSnapshot; 23 | 24 | @property (nonatomic) CGRect smallFrame; 25 | @property (nonatomic) CGRect largeFrame; 26 | @property (nonatomic) CGRect largeCircleFrame; 27 | @property (nonatomic) CGFloat smallScale; 28 | 29 | @end 30 | 31 | @implementation MZMaskZoomTransition 32 | 33 | static NSTimeInterval const MZDefaultDuration = 0.25; 34 | static CGFloat const MZGradientWidth = 80.0f; 35 | static CGFloat const MZDefaultFadeInOffset = 8.0f; 36 | 37 | - (instancetype)init 38 | { 39 | self = [super init]; 40 | if (self) { 41 | _duration = MZDefaultDuration; 42 | _presenting = YES; 43 | _dismissToZeroSize = NO; 44 | } 45 | return self; 46 | } 47 | 48 | #pragma mark - UIViewControllerAnimatedTransitioning 49 | 50 | - (NSTimeInterval)transitionDuration:(id)transitionContext 51 | { 52 | return self.duration; 53 | } 54 | 55 | - (void)animateTransition:(id)transitionContext 56 | { 57 | self.transitionContext = transitionContext; 58 | [self setupPropertiesForTransition]; 59 | 60 | self.toView.hidden = YES; 61 | [self.containerView addSubview:self.toView]; 62 | 63 | // Start appearance transition for source controller because UIKit 64 | // does not remove views from hierarchy when transition is finished. 65 | if (self.presenting) { 66 | [self.fromViewController beginAppearanceTransition:NO animated:YES]; 67 | } 68 | else { 69 | [self.toViewController beginAppearanceTransition:YES animated:YES]; 70 | } 71 | 72 | // Need to wrap the snapshot in a dispatch_async block, otherwise it's nil 73 | dispatch_async(dispatch_get_main_queue(), ^{ 74 | self.largeViewSnapshot = [self.largeView snapshotViewAfterScreenUpdates:NO]; 75 | self.largeFrame = [self.largeView convertRect:self.largeView.bounds toView:nil]; 76 | self.toView.hidden = NO; 77 | 78 | [self animateCircleMask]; 79 | [self animateShadowView]; 80 | [self animateMainView]; 81 | [self fadeViews]; 82 | }); 83 | } 84 | 85 | - (void)setupPropertiesForTransition 86 | { 87 | self.toViewController = [self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 88 | self.fromViewController = [self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 89 | self.containerView = [self.transitionContext containerView]; 90 | self.toView = [self.transitionContext viewForKey:UITransitionContextToViewKey]; 91 | self.fromView = [self.transitionContext viewForKey:UITransitionContextFromViewKey]; 92 | self.maskView = self.presenting ? self.toView : self.fromView; 93 | self.smallFrame = [self.smallView convertRect:self.smallView.bounds toView:nil]; 94 | 95 | if (!self.presenting && self.dismissToZeroSize) { 96 | CGPoint center = [self centerOfRect:self.smallFrame]; 97 | self.smallFrame = CGRectMake(center.x, center.y, 1.0f, 1.0f); 98 | } 99 | 100 | self.largeCircleFrame = [self calculateLargeCircleFrame]; 101 | self.smallScale = CGRectGetWidth(self.smallFrame) / CGRectGetWidth(self.largeCircleFrame); 102 | } 103 | 104 | #pragma mark - Animators 105 | 106 | - (void)animateCircleMask 107 | { 108 | MZGradientCircleLayer *maskLayer = [MZGradientCircleLayer layer]; 109 | maskLayer.position = [self centerOfRect:self.largeCircleFrame]; 110 | maskLayer.frame = self.largeCircleFrame; 111 | maskLayer.gradientWidth = MZGradientWidth; 112 | 113 | CGFloat initialScale = self.presenting ? self.smallScale : 1.0f; 114 | CGFloat finalScale = self.presenting ? 1.0f : self.smallScale; 115 | 116 | maskLayer.transform = CATransform3DMakeScale(initialScale, initialScale, initialScale); 117 | [maskLayer setNeedsDisplay]; 118 | 119 | self.maskView.layer.mask = maskLayer; 120 | 121 | CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 122 | maskLayerAnimation.fromValue = @(initialScale); 123 | maskLayer.transform = CATransform3DMakeScale(finalScale, finalScale, finalScale); 124 | maskLayerAnimation.toValue = @(finalScale); 125 | maskLayerAnimation.duration = [self transitionDuration:self.transitionContext]; 126 | maskLayerAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 127 | maskLayerAnimation.delegate = self; 128 | [maskLayer addAnimation:maskLayerAnimation forKey:@"transform.scale"]; 129 | } 130 | 131 | - (void)animateShadowView 132 | { 133 | self.shadowView = [[UIView alloc] initWithFrame:self.containerView.bounds]; 134 | self.shadowView.backgroundColor = [UIColor colorWithRed:236/255.0f green:236/255.0f blue:236/255.0f alpha:0.6f]; 135 | 136 | self.shadowView.alpha = self.presenting ? 0.0f : 1.0f; 137 | CGFloat finalAlpha = self.presenting ? 1.0f : 0.0f; 138 | 139 | [self.containerView insertSubview:self.shadowView belowSubview:self.maskView]; 140 | 141 | [UIView animateWithDuration:[self transitionDuration:self.transitionContext] 142 | delay:0.0 143 | options:UIViewAnimationOptionCurveEaseOut 144 | animations:^{ 145 | self.shadowView.alpha = finalAlpha; 146 | } completion:nil]; 147 | } 148 | 149 | - (void)animateMainView 150 | { 151 | CGRect initialFrame = self.presenting ? self.smallFrame : self.largeFrame; 152 | CGRect finalFrame = self.presenting ? self.largeFrame: self.smallFrame; 153 | 154 | CGAffineTransform scaleTransform = [self scaleTransformForInitialFrame:initialFrame finalFrame:finalFrame]; 155 | CGAffineTransform initialTransform = self.presenting ? scaleTransform : CGAffineTransformIdentity; 156 | CGAffineTransform finalTransform = self.presenting ? CGAffineTransformIdentity : scaleTransform; 157 | 158 | self.largeViewSnapshot.transform = initialTransform; 159 | self.largeViewSnapshot.center = [self centerOfRect:initialFrame]; 160 | 161 | [self.containerView addSubview:self.largeViewSnapshot]; 162 | self.largeView.hidden = YES; 163 | 164 | [UIView animateWithDuration:[self transitionDuration:self.transitionContext] 165 | delay:0.0 166 | options:UIViewAnimationOptionCurveEaseOut 167 | animations:^{ 168 | self.largeViewSnapshot.transform = finalTransform; 169 | self.largeViewSnapshot.center = [self centerOfRect:finalFrame]; 170 | } 171 | completion:^(BOOL finished) { 172 | self.largeView.hidden = NO; 173 | [self.largeViewSnapshot removeFromSuperview]; 174 | }]; 175 | } 176 | 177 | - (void)fadeViews 178 | { 179 | CGFloat offset = MZDefaultFadeInOffset * [UIScreen mainScreen].scale; 180 | 181 | for (UIView *view in self.viewsToFadeIn) { 182 | NSTimeInterval transitionDuration = [self transitionDuration:self.transitionContext]; 183 | NSTimeInterval duration = self.presenting ? transitionDuration * 0.9 : transitionDuration * 0.4; 184 | NSTimeInterval delay = self.presenting ? duration * 0.9 : 0.0; 185 | 186 | view.alpha = self.presenting ? 0.0f : 1.0f; 187 | CGFloat finalAlpha = self.presenting ? 1.0f : 0.0f; 188 | 189 | [UIView animateWithDuration:duration 190 | delay:delay 191 | options:UIViewAnimationOptionCurveEaseIn 192 | animations:^{ 193 | view.alpha = finalAlpha; 194 | } completion:nil]; 195 | 196 | if (self.presenting) { 197 | CGPoint finalCenter = view.center; 198 | view.center = CGPointMake(view.center.x, view.center.y + offset); 199 | 200 | [UIView animateWithDuration:duration 201 | delay:delay 202 | options:UIViewAnimationOptionCurveEaseOut 203 | animations:^{ 204 | view.center = finalCenter; 205 | } completion:^(BOOL finished) { 206 | if ([view isEqual:self.viewsToFadeIn.lastObject]) { 207 | [self completeTransition]; 208 | } 209 | }]; 210 | } 211 | } 212 | } 213 | 214 | #pragma mark - CAAnimation delegate 215 | 216 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 217 | { 218 | if (!self.presenting || self.viewsToFadeIn.count == 0) { 219 | [self completeTransition]; 220 | } 221 | } 222 | 223 | - (void)completeTransition 224 | { 225 | [self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]]; 226 | self.toView.layer.mask = nil; 227 | [self.shadowView removeFromSuperview]; 228 | 229 | if (self.presenting) { 230 | [self.fromViewController endAppearanceTransition]; 231 | } 232 | else { 233 | [self.toViewController endAppearanceTransition]; 234 | } 235 | } 236 | 237 | #pragma mark - Calculations 238 | 239 | - (CGRect)calculateLargeCircleFrame 240 | { 241 | CGPoint smallViewCenter = [self centerOfRect:self.smallFrame]; 242 | CGPoint extremePoint = [self farthestCornerOfRect:self.maskView.bounds fromPoint:smallViewCenter]; 243 | 244 | CGFloat radiusToEdgeOfView = [self distanceBetweenPoint1:smallViewCenter point2:extremePoint]; 245 | CGFloat largeCircleRadius = radiusToEdgeOfView + MZGradientWidth; 246 | 247 | CGRect zeroRectCenteredOnSmallView = CGRectMake(smallViewCenter.x, smallViewCenter.y, 0.0f, 0.0f); 248 | CGRect largeCircleFrame = CGRectInset(zeroRectCenteredOnSmallView, -largeCircleRadius, -largeCircleRadius); 249 | 250 | return largeCircleFrame; 251 | } 252 | 253 | - (CGPoint)farthestCornerOfRect:(CGRect)rect fromPoint:(CGPoint)point 254 | { 255 | CGPoint extremePoint = CGPointZero; 256 | 257 | if (point.x < CGRectGetMidX(rect)) { 258 | extremePoint.x = CGRectGetMaxX(rect); 259 | } 260 | if (point.y < CGRectGetMidY(rect)) { 261 | extremePoint.y = CGRectGetMaxY(rect); 262 | } 263 | 264 | return extremePoint; 265 | } 266 | 267 | - (CGFloat)distanceBetweenPoint1:(CGPoint)p1 point2:(CGPoint)p2 268 | { 269 | float dx = (float)(p2.x - p1.x); 270 | float dy = (float)(p2.y - p1.y); 271 | 272 | return hypotf(dx, dy); 273 | } 274 | 275 | - (CGAffineTransform)scaleTransformForInitialFrame:(CGRect)initialFrame finalFrame:(CGRect)finalFrame 276 | { 277 | CGFloat xScaleFactor, yScaleFactor; 278 | 279 | if (self.presenting) { 280 | xScaleFactor = CGRectGetWidth(initialFrame) / CGRectGetWidth(finalFrame); 281 | yScaleFactor = CGRectGetHeight(initialFrame) / CGRectGetHeight(finalFrame); 282 | } 283 | else { 284 | xScaleFactor = CGRectGetWidth(finalFrame) / CGRectGetWidth(initialFrame); 285 | yScaleFactor = CGRectGetHeight(finalFrame) / CGRectGetHeight(initialFrame); 286 | } 287 | 288 | return CGAffineTransformMakeScale(xScaleFactor, yScaleFactor); 289 | } 290 | 291 | - (CGPoint)centerOfRect:(CGRect)rect 292 | { 293 | return CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); 294 | } 295 | 296 | @end 297 | -------------------------------------------------------------------------------- /MaskZoomTransition/MZMaskZoomTransitioningDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZMaskZoomTransitioningDelegate.h 3 | // MaskZoomTransition 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol MZMaskZoomTransitionPresentedViewController 12 | 13 | @property (nonatomic, weak) UIView *largeView; 14 | @property (nonatomic, weak) NSArray *viewsToFadeIn; 15 | 16 | @end 17 | 18 | @interface MZMaskZoomTransitioningDelegate : NSObject 19 | 20 | @property (nonatomic, weak) UIView *smallView; 21 | @property (nonatomic) BOOL dismissToZeroSize; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /MaskZoomTransition/MZMaskZoomTransitioningDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZMaskZoomTransitioningDelegate.m 3 | // MaskZoomTransition 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZMaskZoomTransitioningDelegate.h" 10 | #import "MZMaskZoomTransition.h" 11 | #import "UIViewController+MZContentViewController.h" 12 | 13 | @implementation MZMaskZoomTransitioningDelegate 14 | 15 | #pragma mark - UIViewControllerTransitioningDelegate 16 | 17 | - (id)animationControllerForPresentedController:(UIViewController *)presented 18 | presentingController:(UIViewController *)presenting 19 | sourceController:(UIViewController *)source 20 | { 21 | UIViewController *presentedContentViewController = presented.mz_contentViewController; 22 | [presentedContentViewController.view layoutIfNeeded]; 23 | 24 | return [self maskZoomTransitionWithViewController:presentedContentViewController presenting:YES]; 25 | } 26 | 27 | - (id)animationControllerForDismissedController:(UIViewController *)dismissed 28 | { 29 | UIViewController *dismissedContentViewController = dismissed.mz_contentViewController; 30 | 31 | return [self maskZoomTransitionWithViewController:dismissedContentViewController presenting:NO]; 32 | } 33 | 34 | - (MZMaskZoomTransition *)maskZoomTransitionWithViewController:(UIViewController *)viewController presenting:(BOOL)presenting 35 | { 36 | MZMaskZoomTransition *animator; 37 | 38 | if ([viewController conformsToProtocol:@protocol(MZMaskZoomTransitionPresentedViewController)]) { 39 | UIViewController *presentedVC = (UIViewController *)viewController; 40 | 41 | animator = [MZMaskZoomTransition new]; 42 | animator.smallView = self.smallView; 43 | animator.largeView = presentedVC.largeView; 44 | animator.viewsToFadeIn = presentedVC.viewsToFadeIn; 45 | animator.dismissToZeroSize = self.dismissToZeroSize; 46 | 47 | if (!presenting) { 48 | animator.presenting = NO; 49 | animator.duration = 0.2; 50 | } 51 | } 52 | 53 | return animator; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /MaskZoomTransition/UIViewController+MZContentViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MZContentViewController.h 3 | // MaskZoomTransition 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (MZContentViewController) 12 | 13 | @property (nonatomic, readonly) UIViewController *mz_contentViewController; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /MaskZoomTransition/UIViewController+MZContentViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MZContentViewController.m 3 | // MaskZoomTransition 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+MZContentViewController.h" 10 | 11 | @implementation UIViewController (MZContentViewController) 12 | 13 | - (UIViewController *)mz_contentViewController 14 | { 15 | if ([self isKindOfClass:[UINavigationController class]]) { 16 | UINavigationController *navcon = (UINavigationController *)self; 17 | return navcon.visibleViewController; 18 | } 19 | return self; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8284FB2C1C21203500CD7642 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8284FB2B1C21203500CD7642 /* main.m */; }; 11 | 8284FB2F1C21203500CD7642 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8284FB2E1C21203500CD7642 /* AppDelegate.m */; }; 12 | 8284FB351C21203500CD7642 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8284FB331C21203500CD7642 /* Main.storyboard */; }; 13 | 8284FB371C21203500CD7642 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8284FB361C21203500CD7642 /* Assets.xcassets */; }; 14 | 8284FB3A1C21203500CD7642 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8284FB381C21203500CD7642 /* LaunchScreen.storyboard */; }; 15 | 8284FB481C21211500CD7642 /* MZGradientCircleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8284FB431C21211500CD7642 /* MZGradientCircleLayer.m */; }; 16 | 8284FB491C21211500CD7642 /* MZMaskZoomTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 8284FB451C21211500CD7642 /* MZMaskZoomTransition.m */; }; 17 | 8284FB4A1C21211500CD7642 /* MZMaskZoomTransitioningDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8284FB471C21211500CD7642 /* MZMaskZoomTransitioningDelegate.m */; }; 18 | 8284FB501C2123DA00CD7642 /* UIViewController+MZContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8284FB4F1C2123DA00CD7642 /* UIViewController+MZContentViewController.m */; }; 19 | 82962D1A1C59C17300CC6075 /* MZColorsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 82962D121C59C17300CC6075 /* MZColorsViewController.m */; }; 20 | 82962D1B1C59C17300CC6075 /* MZColorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 82962D141C59C17300CC6075 /* MZColorViewController.m */; }; 21 | 82962D1C1C59C17300CC6075 /* MZCircleButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 82962D171C59C17300CC6075 /* MZCircleButton.m */; }; 22 | 82962D1D1C59C17300CC6075 /* MZCircleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 82962D191C59C17300CC6075 /* MZCircleView.m */; }; 23 | 8298B37E1C5884430000C27A /* MZProfileButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 8298B37D1C5884430000C27A /* MZProfileButton.m */; }; 24 | 82B6AD331C4DF30A00734CCC /* Colors.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 82B6AD311C4DF30A00734CCC /* Colors.storyboard */; }; 25 | 82B6AD361C4DF3B400734CCC /* People.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 82B6AD341C4DF3B400734CCC /* People.storyboard */; }; 26 | 82B6AD931C4F591000734CCC /* MZPerson.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6AD861C4F591000734CCC /* MZPerson.m */; }; 27 | 82B6AD941C4F591000734CCC /* NSString+MZProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6AD881C4F591000734CCC /* NSString+MZProfile.m */; }; 28 | 82B6AD951C4F591000734CCC /* MZPeopleTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6AD8B1C4F591000734CCC /* MZPeopleTableViewController.m */; }; 29 | 82B6AD961C4F591000734CCC /* MZCircleImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6AD8E1C4F591000734CCC /* MZCircleImageView.m */; }; 30 | 82B6AD971C4F591000734CCC /* MZPersonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6AD901C4F591000734CCC /* MZPersonCell.m */; }; 31 | 82B6AD9A1C4F626E00734CCC /* MZProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6AD991C4F626E00734CCC /* MZProfile.m */; }; 32 | 82B6AD9D1C5028AD00734CCC /* MZProfilesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6AD9C1C5028AD00734CCC /* MZProfilesController.m */; }; 33 | 82B6ADA21C50290300734CCC /* MZPeople.plist in Resources */ = {isa = PBXBuildFile; fileRef = 82B6AD9F1C50290300734CCC /* MZPeople.plist */; }; 34 | 82B6ADA31C50290300734CCC /* MZPersonStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADA11C50290300734CCC /* MZPersonStore.m */; }; 35 | 82B6ADBE1C55DC3200734CCC /* MZTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADBB1C55DC3200734CCC /* MZTheme.m */; }; 36 | 82B6ADC21C55DC7400734CCC /* UIColor+MZTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADC11C55DC7400734CCC /* UIColor+MZTheme.m */; }; 37 | 82B6ADE51C583ECB00734CCC /* MZProfileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADE41C583ECB00734CCC /* MZProfileViewController.m */; }; 38 | 82B6ADEC1C583ED800734CCC /* MZProfileCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADE71C583ED800734CCC /* MZProfileCell.m */; }; 39 | 82B6ADED1C583ED800734CCC /* MZLineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADE91C583ED800734CCC /* MZLineView.m */; }; 40 | 82B6ADEE1C583ED800734CCC /* MZTopImageButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADEB1C583ED800734CCC /* MZTopImageButton.m */; }; 41 | 82B6ADF51C583F9400734CCC /* UIView+MZEmbed.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADF21C583F9400734CCC /* UIView+MZEmbed.m */; }; 42 | 82B6ADFA1C58498300734CCC /* UIView+MZNavigationBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 82B6ADF91C58498300734CCC /* UIView+MZNavigationBar.m */; }; 43 | /* End PBXBuildFile section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 8284FB271C21203500CD7642 /* MaskZoom.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MaskZoom.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 8284FB2B1C21203500CD7642 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 48 | 8284FB2D1C21203500CD7642 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 49 | 8284FB2E1C21203500CD7642 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 50 | 8284FB341C21203500CD7642 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 8284FB361C21203500CD7642 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 52 | 8284FB391C21203500CD7642 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53 | 8284FB3B1C21203500CD7642 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 8284FB421C21211500CD7642 /* MZGradientCircleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZGradientCircleLayer.h; sourceTree = ""; }; 55 | 8284FB431C21211500CD7642 /* MZGradientCircleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZGradientCircleLayer.m; sourceTree = ""; }; 56 | 8284FB441C21211500CD7642 /* MZMaskZoomTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZMaskZoomTransition.h; sourceTree = ""; }; 57 | 8284FB451C21211500CD7642 /* MZMaskZoomTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZMaskZoomTransition.m; sourceTree = ""; }; 58 | 8284FB461C21211500CD7642 /* MZMaskZoomTransitioningDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZMaskZoomTransitioningDelegate.h; sourceTree = ""; }; 59 | 8284FB471C21211500CD7642 /* MZMaskZoomTransitioningDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZMaskZoomTransitioningDelegate.m; sourceTree = ""; }; 60 | 8284FB4E1C2123DA00CD7642 /* UIViewController+MZContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+MZContentViewController.h"; sourceTree = ""; }; 61 | 8284FB4F1C2123DA00CD7642 /* UIViewController+MZContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+MZContentViewController.m"; sourceTree = ""; }; 62 | 82962D111C59C17300CC6075 /* MZColorsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZColorsViewController.h; sourceTree = ""; }; 63 | 82962D121C59C17300CC6075 /* MZColorsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZColorsViewController.m; sourceTree = ""; }; 64 | 82962D131C59C17300CC6075 /* MZColorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZColorViewController.h; sourceTree = ""; }; 65 | 82962D141C59C17300CC6075 /* MZColorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZColorViewController.m; sourceTree = ""; }; 66 | 82962D161C59C17300CC6075 /* MZCircleButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZCircleButton.h; sourceTree = ""; }; 67 | 82962D171C59C17300CC6075 /* MZCircleButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZCircleButton.m; sourceTree = ""; }; 68 | 82962D181C59C17300CC6075 /* MZCircleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZCircleView.h; sourceTree = ""; }; 69 | 82962D191C59C17300CC6075 /* MZCircleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZCircleView.m; sourceTree = ""; }; 70 | 8298B37C1C5884430000C27A /* MZProfileButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZProfileButton.h; sourceTree = ""; }; 71 | 8298B37D1C5884430000C27A /* MZProfileButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZProfileButton.m; sourceTree = ""; }; 72 | 82B6AD321C4DF30A00734CCC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Colors.storyboard; sourceTree = ""; }; 73 | 82B6AD351C4DF3B400734CCC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/People.storyboard; sourceTree = ""; }; 74 | 82B6AD851C4F591000734CCC /* MZPerson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZPerson.h; sourceTree = ""; }; 75 | 82B6AD861C4F591000734CCC /* MZPerson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZPerson.m; sourceTree = ""; }; 76 | 82B6AD871C4F591000734CCC /* NSString+MZProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MZProfile.h"; sourceTree = ""; }; 77 | 82B6AD881C4F591000734CCC /* NSString+MZProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MZProfile.m"; sourceTree = ""; }; 78 | 82B6AD8A1C4F591000734CCC /* MZPeopleTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZPeopleTableViewController.h; sourceTree = ""; }; 79 | 82B6AD8B1C4F591000734CCC /* MZPeopleTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZPeopleTableViewController.m; sourceTree = ""; }; 80 | 82B6AD8D1C4F591000734CCC /* MZCircleImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZCircleImageView.h; sourceTree = ""; }; 81 | 82B6AD8E1C4F591000734CCC /* MZCircleImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZCircleImageView.m; sourceTree = ""; }; 82 | 82B6AD8F1C4F591000734CCC /* MZPersonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZPersonCell.h; sourceTree = ""; }; 83 | 82B6AD901C4F591000734CCC /* MZPersonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZPersonCell.m; sourceTree = ""; }; 84 | 82B6AD981C4F626E00734CCC /* MZProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZProfile.h; sourceTree = ""; }; 85 | 82B6AD991C4F626E00734CCC /* MZProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZProfile.m; sourceTree = ""; }; 86 | 82B6AD9B1C5028AD00734CCC /* MZProfilesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZProfilesController.h; sourceTree = ""; }; 87 | 82B6AD9C1C5028AD00734CCC /* MZProfilesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZProfilesController.m; sourceTree = ""; }; 88 | 82B6AD9F1C50290300734CCC /* MZPeople.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = MZPeople.plist; sourceTree = ""; }; 89 | 82B6ADA01C50290300734CCC /* MZPersonStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZPersonStore.h; sourceTree = ""; }; 90 | 82B6ADA11C50290300734CCC /* MZPersonStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZPersonStore.m; sourceTree = ""; }; 91 | 82B6ADBA1C55DC3200734CCC /* MZTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZTheme.h; sourceTree = ""; }; 92 | 82B6ADBB1C55DC3200734CCC /* MZTheme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZTheme.m; sourceTree = ""; }; 93 | 82B6ADC01C55DC7400734CCC /* UIColor+MZTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+MZTheme.h"; sourceTree = ""; }; 94 | 82B6ADC11C55DC7400734CCC /* UIColor+MZTheme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+MZTheme.m"; sourceTree = ""; }; 95 | 82B6ADE31C583ECB00734CCC /* MZProfileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZProfileViewController.h; sourceTree = ""; }; 96 | 82B6ADE41C583ECB00734CCC /* MZProfileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZProfileViewController.m; sourceTree = ""; }; 97 | 82B6ADE61C583ED800734CCC /* MZProfileCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZProfileCell.h; sourceTree = ""; }; 98 | 82B6ADE71C583ED800734CCC /* MZProfileCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZProfileCell.m; sourceTree = ""; }; 99 | 82B6ADE81C583ED800734CCC /* MZLineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZLineView.h; sourceTree = ""; }; 100 | 82B6ADE91C583ED800734CCC /* MZLineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZLineView.m; sourceTree = ""; }; 101 | 82B6ADEA1C583ED800734CCC /* MZTopImageButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MZTopImageButton.h; sourceTree = ""; }; 102 | 82B6ADEB1C583ED800734CCC /* MZTopImageButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MZTopImageButton.m; sourceTree = ""; }; 103 | 82B6ADF11C583F9400734CCC /* UIView+MZEmbed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+MZEmbed.h"; sourceTree = ""; }; 104 | 82B6ADF21C583F9400734CCC /* UIView+MZEmbed.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+MZEmbed.m"; sourceTree = ""; }; 105 | 82B6ADF81C58498300734CCC /* UIView+MZNavigationBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+MZNavigationBar.h"; sourceTree = ""; }; 106 | 82B6ADF91C58498300734CCC /* UIView+MZNavigationBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+MZNavigationBar.m"; sourceTree = ""; }; 107 | /* End PBXFileReference section */ 108 | 109 | /* Begin PBXFrameworksBuildPhase section */ 110 | 8284FB241C21203500CD7642 /* Frameworks */ = { 111 | isa = PBXFrameworksBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | ); 115 | runOnlyForDeploymentPostprocessing = 0; 116 | }; 117 | /* End PBXFrameworksBuildPhase section */ 118 | 119 | /* Begin PBXGroup section */ 120 | 8284FB1E1C21203500CD7642 = { 121 | isa = PBXGroup; 122 | children = ( 123 | 8284FB411C21211500CD7642 /* MaskZoomTransition */, 124 | 8284FB291C21203500CD7642 /* MaskZoomTransitionDemo */, 125 | 8284FB281C21203500CD7642 /* Products */, 126 | ); 127 | sourceTree = ""; 128 | }; 129 | 8284FB281C21203500CD7642 /* Products */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 8284FB271C21203500CD7642 /* MaskZoom.app */, 133 | ); 134 | name = Products; 135 | sourceTree = ""; 136 | }; 137 | 8284FB291C21203500CD7642 /* MaskZoomTransitionDemo */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 8284FB2D1C21203500CD7642 /* AppDelegate.h */, 141 | 8284FB2E1C21203500CD7642 /* AppDelegate.m */, 142 | 82B6ADB91C55DC3200734CCC /* Theme */, 143 | 82B6ADEF1C583F9400734CCC /* Categories */, 144 | 82962D0F1C59C17300CC6075 /* Colors */, 145 | 82B6AD631C4F32E900734CCC /* People */, 146 | 82B6AD621C4F306D00734CCC /* Storyboards */, 147 | 8284FB361C21203500CD7642 /* Assets.xcassets */, 148 | 8284FB381C21203500CD7642 /* LaunchScreen.storyboard */, 149 | 8284FB3B1C21203500CD7642 /* Info.plist */, 150 | 8284FB2A1C21203500CD7642 /* Supporting Files */, 151 | ); 152 | path = MaskZoomTransitionDemo; 153 | sourceTree = ""; 154 | }; 155 | 8284FB2A1C21203500CD7642 /* Supporting Files */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 8284FB2B1C21203500CD7642 /* main.m */, 159 | ); 160 | name = "Supporting Files"; 161 | sourceTree = ""; 162 | }; 163 | 8284FB411C21211500CD7642 /* MaskZoomTransition */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 8284FB421C21211500CD7642 /* MZGradientCircleLayer.h */, 167 | 8284FB431C21211500CD7642 /* MZGradientCircleLayer.m */, 168 | 8284FB441C21211500CD7642 /* MZMaskZoomTransition.h */, 169 | 8284FB451C21211500CD7642 /* MZMaskZoomTransition.m */, 170 | 8284FB461C21211500CD7642 /* MZMaskZoomTransitioningDelegate.h */, 171 | 8284FB471C21211500CD7642 /* MZMaskZoomTransitioningDelegate.m */, 172 | 8284FB4E1C2123DA00CD7642 /* UIViewController+MZContentViewController.h */, 173 | 8284FB4F1C2123DA00CD7642 /* UIViewController+MZContentViewController.m */, 174 | ); 175 | path = MaskZoomTransition; 176 | sourceTree = ""; 177 | }; 178 | 82962D0F1C59C17300CC6075 /* Colors */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 82962D101C59C17300CC6075 /* View Controllers */, 182 | 82962D151C59C17300CC6075 /* Views */, 183 | ); 184 | path = Colors; 185 | sourceTree = ""; 186 | }; 187 | 82962D101C59C17300CC6075 /* View Controllers */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 82962D111C59C17300CC6075 /* MZColorsViewController.h */, 191 | 82962D121C59C17300CC6075 /* MZColorsViewController.m */, 192 | 82962D131C59C17300CC6075 /* MZColorViewController.h */, 193 | 82962D141C59C17300CC6075 /* MZColorViewController.m */, 194 | ); 195 | path = "View Controllers"; 196 | sourceTree = ""; 197 | }; 198 | 82962D151C59C17300CC6075 /* Views */ = { 199 | isa = PBXGroup; 200 | children = ( 201 | 82962D161C59C17300CC6075 /* MZCircleButton.h */, 202 | 82962D171C59C17300CC6075 /* MZCircleButton.m */, 203 | 82962D181C59C17300CC6075 /* MZCircleView.h */, 204 | 82962D191C59C17300CC6075 /* MZCircleView.m */, 205 | ); 206 | path = Views; 207 | sourceTree = ""; 208 | }; 209 | 82B6AD621C4F306D00734CCC /* Storyboards */ = { 210 | isa = PBXGroup; 211 | children = ( 212 | 8284FB331C21203500CD7642 /* Main.storyboard */, 213 | 82B6AD311C4DF30A00734CCC /* Colors.storyboard */, 214 | 82B6AD341C4DF3B400734CCC /* People.storyboard */, 215 | ); 216 | name = Storyboards; 217 | sourceTree = ""; 218 | }; 219 | 82B6AD631C4F32E900734CCC /* People */ = { 220 | isa = PBXGroup; 221 | children = ( 222 | 82B6AD9E1C50290300734CCC /* Data Store */, 223 | 82B6AD831C4F591000734CCC /* Models */, 224 | 82B6AD801C4F591000734CCC /* Controllers */, 225 | 82B6AD891C4F591000734CCC /* View Controllers */, 226 | 82B6AD8C1C4F591000734CCC /* Views */, 227 | ); 228 | path = People; 229 | sourceTree = ""; 230 | }; 231 | 82B6AD801C4F591000734CCC /* Controllers */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | 82B6AD9B1C5028AD00734CCC /* MZProfilesController.h */, 235 | 82B6AD9C1C5028AD00734CCC /* MZProfilesController.m */, 236 | ); 237 | path = Controllers; 238 | sourceTree = ""; 239 | }; 240 | 82B6AD831C4F591000734CCC /* Models */ = { 241 | isa = PBXGroup; 242 | children = ( 243 | 82B6AD851C4F591000734CCC /* MZPerson.h */, 244 | 82B6AD861C4F591000734CCC /* MZPerson.m */, 245 | 82B6AD981C4F626E00734CCC /* MZProfile.h */, 246 | 82B6AD991C4F626E00734CCC /* MZProfile.m */, 247 | 82B6AD871C4F591000734CCC /* NSString+MZProfile.h */, 248 | 82B6AD881C4F591000734CCC /* NSString+MZProfile.m */, 249 | ); 250 | path = Models; 251 | sourceTree = ""; 252 | }; 253 | 82B6AD891C4F591000734CCC /* View Controllers */ = { 254 | isa = PBXGroup; 255 | children = ( 256 | 82B6AD8A1C4F591000734CCC /* MZPeopleTableViewController.h */, 257 | 82B6AD8B1C4F591000734CCC /* MZPeopleTableViewController.m */, 258 | 82B6ADE31C583ECB00734CCC /* MZProfileViewController.h */, 259 | 82B6ADE41C583ECB00734CCC /* MZProfileViewController.m */, 260 | ); 261 | path = "View Controllers"; 262 | sourceTree = ""; 263 | }; 264 | 82B6AD8C1C4F591000734CCC /* Views */ = { 265 | isa = PBXGroup; 266 | children = ( 267 | 82B6AD8D1C4F591000734CCC /* MZCircleImageView.h */, 268 | 82B6AD8E1C4F591000734CCC /* MZCircleImageView.m */, 269 | 82B6ADE81C583ED800734CCC /* MZLineView.h */, 270 | 82B6ADE91C583ED800734CCC /* MZLineView.m */, 271 | 8298B37C1C5884430000C27A /* MZProfileButton.h */, 272 | 8298B37D1C5884430000C27A /* MZProfileButton.m */, 273 | 82B6AD8F1C4F591000734CCC /* MZPersonCell.h */, 274 | 82B6AD901C4F591000734CCC /* MZPersonCell.m */, 275 | 82B6ADE61C583ED800734CCC /* MZProfileCell.h */, 276 | 82B6ADE71C583ED800734CCC /* MZProfileCell.m */, 277 | 82B6ADEA1C583ED800734CCC /* MZTopImageButton.h */, 278 | 82B6ADEB1C583ED800734CCC /* MZTopImageButton.m */, 279 | ); 280 | path = Views; 281 | sourceTree = ""; 282 | }; 283 | 82B6AD9E1C50290300734CCC /* Data Store */ = { 284 | isa = PBXGroup; 285 | children = ( 286 | 82B6AD9F1C50290300734CCC /* MZPeople.plist */, 287 | 82B6ADA01C50290300734CCC /* MZPersonStore.h */, 288 | 82B6ADA11C50290300734CCC /* MZPersonStore.m */, 289 | ); 290 | path = "Data Store"; 291 | sourceTree = ""; 292 | }; 293 | 82B6ADB91C55DC3200734CCC /* Theme */ = { 294 | isa = PBXGroup; 295 | children = ( 296 | 82B6ADBA1C55DC3200734CCC /* MZTheme.h */, 297 | 82B6ADBB1C55DC3200734CCC /* MZTheme.m */, 298 | 82B6ADC01C55DC7400734CCC /* UIColor+MZTheme.h */, 299 | 82B6ADC11C55DC7400734CCC /* UIColor+MZTheme.m */, 300 | ); 301 | path = Theme; 302 | sourceTree = ""; 303 | }; 304 | 82B6ADEF1C583F9400734CCC /* Categories */ = { 305 | isa = PBXGroup; 306 | children = ( 307 | 82B6ADF71C58498300734CCC /* Navigation */, 308 | 82B6ADF01C583F9400734CCC /* View Containment */, 309 | ); 310 | path = Categories; 311 | sourceTree = ""; 312 | }; 313 | 82B6ADF01C583F9400734CCC /* View Containment */ = { 314 | isa = PBXGroup; 315 | children = ( 316 | 82B6ADF11C583F9400734CCC /* UIView+MZEmbed.h */, 317 | 82B6ADF21C583F9400734CCC /* UIView+MZEmbed.m */, 318 | ); 319 | path = "View Containment"; 320 | sourceTree = ""; 321 | }; 322 | 82B6ADF71C58498300734CCC /* Navigation */ = { 323 | isa = PBXGroup; 324 | children = ( 325 | 82B6ADF81C58498300734CCC /* UIView+MZNavigationBar.h */, 326 | 82B6ADF91C58498300734CCC /* UIView+MZNavigationBar.m */, 327 | ); 328 | path = Navigation; 329 | sourceTree = ""; 330 | }; 331 | /* End PBXGroup section */ 332 | 333 | /* Begin PBXNativeTarget section */ 334 | 8284FB261C21203500CD7642 /* MaskZoomTransitionDemo */ = { 335 | isa = PBXNativeTarget; 336 | buildConfigurationList = 8284FB3E1C21203500CD7642 /* Build configuration list for PBXNativeTarget "MaskZoomTransitionDemo" */; 337 | buildPhases = ( 338 | 8284FB231C21203500CD7642 /* Sources */, 339 | 8284FB241C21203500CD7642 /* Frameworks */, 340 | 8284FB251C21203500CD7642 /* Resources */, 341 | ); 342 | buildRules = ( 343 | ); 344 | dependencies = ( 345 | ); 346 | name = MaskZoomTransitionDemo; 347 | productName = MaskZoomTransitionDemo; 348 | productReference = 8284FB271C21203500CD7642 /* MaskZoom.app */; 349 | productType = "com.apple.product-type.application"; 350 | }; 351 | /* End PBXNativeTarget section */ 352 | 353 | /* Begin PBXProject section */ 354 | 8284FB1F1C21203500CD7642 /* Project object */ = { 355 | isa = PBXProject; 356 | attributes = { 357 | CLASSPREFIX = MZ; 358 | LastUpgradeCheck = 0720; 359 | ORGANIZATIONNAME = "Stephanie Sharp"; 360 | TargetAttributes = { 361 | 8284FB261C21203500CD7642 = { 362 | CreatedOnToolsVersion = 7.2; 363 | }; 364 | }; 365 | }; 366 | buildConfigurationList = 8284FB221C21203500CD7642 /* Build configuration list for PBXProject "MaskZoomTransitionDemo" */; 367 | compatibilityVersion = "Xcode 3.2"; 368 | developmentRegion = English; 369 | hasScannedForEncodings = 0; 370 | knownRegions = ( 371 | en, 372 | Base, 373 | ); 374 | mainGroup = 8284FB1E1C21203500CD7642; 375 | productRefGroup = 8284FB281C21203500CD7642 /* Products */; 376 | projectDirPath = ""; 377 | projectRoot = ""; 378 | targets = ( 379 | 8284FB261C21203500CD7642 /* MaskZoomTransitionDemo */, 380 | ); 381 | }; 382 | /* End PBXProject section */ 383 | 384 | /* Begin PBXResourcesBuildPhase section */ 385 | 8284FB251C21203500CD7642 /* Resources */ = { 386 | isa = PBXResourcesBuildPhase; 387 | buildActionMask = 2147483647; 388 | files = ( 389 | 82B6ADA21C50290300734CCC /* MZPeople.plist in Resources */, 390 | 8284FB3A1C21203500CD7642 /* LaunchScreen.storyboard in Resources */, 391 | 8284FB371C21203500CD7642 /* Assets.xcassets in Resources */, 392 | 82B6AD361C4DF3B400734CCC /* People.storyboard in Resources */, 393 | 82B6AD331C4DF30A00734CCC /* Colors.storyboard in Resources */, 394 | 8284FB351C21203500CD7642 /* Main.storyboard in Resources */, 395 | ); 396 | runOnlyForDeploymentPostprocessing = 0; 397 | }; 398 | /* End PBXResourcesBuildPhase section */ 399 | 400 | /* Begin PBXSourcesBuildPhase section */ 401 | 8284FB231C21203500CD7642 /* Sources */ = { 402 | isa = PBXSourcesBuildPhase; 403 | buildActionMask = 2147483647; 404 | files = ( 405 | 82B6ADC21C55DC7400734CCC /* UIColor+MZTheme.m in Sources */, 406 | 82B6ADEC1C583ED800734CCC /* MZProfileCell.m in Sources */, 407 | 8284FB481C21211500CD7642 /* MZGradientCircleLayer.m in Sources */, 408 | 8284FB2F1C21203500CD7642 /* AppDelegate.m in Sources */, 409 | 8284FB4A1C21211500CD7642 /* MZMaskZoomTransitioningDelegate.m in Sources */, 410 | 82B6AD951C4F591000734CCC /* MZPeopleTableViewController.m in Sources */, 411 | 82B6AD971C4F591000734CCC /* MZPersonCell.m in Sources */, 412 | 82B6AD961C4F591000734CCC /* MZCircleImageView.m in Sources */, 413 | 82B6ADBE1C55DC3200734CCC /* MZTheme.m in Sources */, 414 | 82B6ADF51C583F9400734CCC /* UIView+MZEmbed.m in Sources */, 415 | 82B6ADFA1C58498300734CCC /* UIView+MZNavigationBar.m in Sources */, 416 | 8284FB501C2123DA00CD7642 /* UIViewController+MZContentViewController.m in Sources */, 417 | 82B6ADED1C583ED800734CCC /* MZLineView.m in Sources */, 418 | 82B6AD9D1C5028AD00734CCC /* MZProfilesController.m in Sources */, 419 | 82962D1B1C59C17300CC6075 /* MZColorViewController.m in Sources */, 420 | 82B6ADEE1C583ED800734CCC /* MZTopImageButton.m in Sources */, 421 | 8284FB491C21211500CD7642 /* MZMaskZoomTransition.m in Sources */, 422 | 82B6ADA31C50290300734CCC /* MZPersonStore.m in Sources */, 423 | 8284FB2C1C21203500CD7642 /* main.m in Sources */, 424 | 82B6AD931C4F591000734CCC /* MZPerson.m in Sources */, 425 | 8298B37E1C5884430000C27A /* MZProfileButton.m in Sources */, 426 | 82B6AD941C4F591000734CCC /* NSString+MZProfile.m in Sources */, 427 | 82962D1C1C59C17300CC6075 /* MZCircleButton.m in Sources */, 428 | 82B6AD9A1C4F626E00734CCC /* MZProfile.m in Sources */, 429 | 82962D1D1C59C17300CC6075 /* MZCircleView.m in Sources */, 430 | 82B6ADE51C583ECB00734CCC /* MZProfileViewController.m in Sources */, 431 | 82962D1A1C59C17300CC6075 /* MZColorsViewController.m in Sources */, 432 | ); 433 | runOnlyForDeploymentPostprocessing = 0; 434 | }; 435 | /* End PBXSourcesBuildPhase section */ 436 | 437 | /* Begin PBXVariantGroup section */ 438 | 8284FB331C21203500CD7642 /* Main.storyboard */ = { 439 | isa = PBXVariantGroup; 440 | children = ( 441 | 8284FB341C21203500CD7642 /* Base */, 442 | ); 443 | name = Main.storyboard; 444 | sourceTree = ""; 445 | }; 446 | 8284FB381C21203500CD7642 /* LaunchScreen.storyboard */ = { 447 | isa = PBXVariantGroup; 448 | children = ( 449 | 8284FB391C21203500CD7642 /* Base */, 450 | ); 451 | name = LaunchScreen.storyboard; 452 | sourceTree = ""; 453 | }; 454 | 82B6AD311C4DF30A00734CCC /* Colors.storyboard */ = { 455 | isa = PBXVariantGroup; 456 | children = ( 457 | 82B6AD321C4DF30A00734CCC /* Base */, 458 | ); 459 | name = Colors.storyboard; 460 | sourceTree = ""; 461 | }; 462 | 82B6AD341C4DF3B400734CCC /* People.storyboard */ = { 463 | isa = PBXVariantGroup; 464 | children = ( 465 | 82B6AD351C4DF3B400734CCC /* Base */, 466 | ); 467 | name = People.storyboard; 468 | sourceTree = ""; 469 | }; 470 | /* End PBXVariantGroup section */ 471 | 472 | /* Begin XCBuildConfiguration section */ 473 | 8284FB3C1C21203500CD7642 /* Debug */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | ALWAYS_SEARCH_USER_PATHS = NO; 477 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 478 | CLANG_CXX_LIBRARY = "libc++"; 479 | CLANG_ENABLE_MODULES = YES; 480 | CLANG_ENABLE_OBJC_ARC = YES; 481 | CLANG_WARN_BOOL_CONVERSION = YES; 482 | CLANG_WARN_CONSTANT_CONVERSION = YES; 483 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 484 | CLANG_WARN_EMPTY_BODY = YES; 485 | CLANG_WARN_ENUM_CONVERSION = YES; 486 | CLANG_WARN_INT_CONVERSION = YES; 487 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 488 | CLANG_WARN_UNREACHABLE_CODE = YES; 489 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 490 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 491 | COPY_PHASE_STRIP = NO; 492 | DEBUG_INFORMATION_FORMAT = dwarf; 493 | ENABLE_STRICT_OBJC_MSGSEND = YES; 494 | ENABLE_TESTABILITY = YES; 495 | GCC_C_LANGUAGE_STANDARD = gnu99; 496 | GCC_DYNAMIC_NO_PIC = NO; 497 | GCC_NO_COMMON_BLOCKS = YES; 498 | GCC_OPTIMIZATION_LEVEL = 0; 499 | GCC_PREPROCESSOR_DEFINITIONS = ( 500 | "DEBUG=1", 501 | "$(inherited)", 502 | ); 503 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 504 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 505 | GCC_WARN_UNDECLARED_SELECTOR = YES; 506 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 507 | GCC_WARN_UNUSED_FUNCTION = YES; 508 | GCC_WARN_UNUSED_VARIABLE = YES; 509 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 510 | MTL_ENABLE_DEBUG_INFO = YES; 511 | ONLY_ACTIVE_ARCH = YES; 512 | SDKROOT = iphoneos; 513 | TARGETED_DEVICE_FAMILY = "1,2"; 514 | }; 515 | name = Debug; 516 | }; 517 | 8284FB3D1C21203500CD7642 /* Release */ = { 518 | isa = XCBuildConfiguration; 519 | buildSettings = { 520 | ALWAYS_SEARCH_USER_PATHS = NO; 521 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 522 | CLANG_CXX_LIBRARY = "libc++"; 523 | CLANG_ENABLE_MODULES = YES; 524 | CLANG_ENABLE_OBJC_ARC = YES; 525 | CLANG_WARN_BOOL_CONVERSION = YES; 526 | CLANG_WARN_CONSTANT_CONVERSION = YES; 527 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 528 | CLANG_WARN_EMPTY_BODY = YES; 529 | CLANG_WARN_ENUM_CONVERSION = YES; 530 | CLANG_WARN_INT_CONVERSION = YES; 531 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 532 | CLANG_WARN_UNREACHABLE_CODE = YES; 533 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 534 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 535 | COPY_PHASE_STRIP = NO; 536 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 537 | ENABLE_NS_ASSERTIONS = NO; 538 | ENABLE_STRICT_OBJC_MSGSEND = YES; 539 | GCC_C_LANGUAGE_STANDARD = gnu99; 540 | GCC_NO_COMMON_BLOCKS = YES; 541 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 542 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 543 | GCC_WARN_UNDECLARED_SELECTOR = YES; 544 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 545 | GCC_WARN_UNUSED_FUNCTION = YES; 546 | GCC_WARN_UNUSED_VARIABLE = YES; 547 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 548 | MTL_ENABLE_DEBUG_INFO = NO; 549 | SDKROOT = iphoneos; 550 | TARGETED_DEVICE_FAMILY = "1,2"; 551 | VALIDATE_PRODUCT = YES; 552 | }; 553 | name = Release; 554 | }; 555 | 8284FB3F1C21203500CD7642 /* Debug */ = { 556 | isa = XCBuildConfiguration; 557 | buildSettings = { 558 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 559 | INFOPLIST_FILE = MaskZoomTransitionDemo/Info.plist; 560 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 561 | PRODUCT_BUNDLE_IDENTIFIER = com.ssharp.MaskZoomTransitionDemo; 562 | PRODUCT_NAME = MaskZoom; 563 | }; 564 | name = Debug; 565 | }; 566 | 8284FB401C21203500CD7642 /* Release */ = { 567 | isa = XCBuildConfiguration; 568 | buildSettings = { 569 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 570 | INFOPLIST_FILE = MaskZoomTransitionDemo/Info.plist; 571 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 572 | PRODUCT_BUNDLE_IDENTIFIER = com.ssharp.MaskZoomTransitionDemo; 573 | PRODUCT_NAME = MaskZoom; 574 | }; 575 | name = Release; 576 | }; 577 | /* End XCBuildConfiguration section */ 578 | 579 | /* Begin XCConfigurationList section */ 580 | 8284FB221C21203500CD7642 /* Build configuration list for PBXProject "MaskZoomTransitionDemo" */ = { 581 | isa = XCConfigurationList; 582 | buildConfigurations = ( 583 | 8284FB3C1C21203500CD7642 /* Debug */, 584 | 8284FB3D1C21203500CD7642 /* Release */, 585 | ); 586 | defaultConfigurationIsVisible = 0; 587 | defaultConfigurationName = Release; 588 | }; 589 | 8284FB3E1C21203500CD7642 /* Build configuration list for PBXNativeTarget "MaskZoomTransitionDemo" */ = { 590 | isa = XCConfigurationList; 591 | buildConfigurations = ( 592 | 8284FB3F1C21203500CD7642 /* Debug */, 593 | 8284FB401C21203500CD7642 /* Release */, 594 | ); 595 | defaultConfigurationIsVisible = 0; 596 | defaultConfigurationName = Release; 597 | }; 598 | /* End XCConfigurationList section */ 599 | }; 600 | rootObject = 8284FB1F1C21203500CD7642 /* Project object */; 601 | } 602 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo.xcodeproj/xcshareddata/xcschemes/MaskZoomTransitionDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "MZTheme.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | [MZTheme setupAppTheme]; 22 | 23 | return YES; 24 | } 25 | 26 | - (void)applicationWillResignActive:(UIApplication *)application { 27 | // 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. 28 | // 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. 29 | } 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application { 32 | // 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. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | - (void)applicationDidBecomeActive:(UIApplication *)application { 41 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 42 | } 43 | 44 | - (void)applicationWillTerminate:(UIApplication *)application { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "app-icon-29@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "app-icon-29@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "app-icon-40@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "app-icon-40@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "app-icon-60@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "app-icon-60@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "29x29", 41 | "idiom" : "ipad", 42 | "filename" : "app-icon-29.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "29x29", 47 | "idiom" : "ipad", 48 | "filename" : "app-icon-29@2x-1.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "40x40", 53 | "idiom" : "ipad", 54 | "filename" : "app-icon-40.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "40x40", 59 | "idiom" : "ipad", 60 | "filename" : "app-icon-40@2x-1.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "76x76", 65 | "idiom" : "ipad", 66 | "filename" : "app-icon-76.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "76x76", 71 | "idiom" : "ipad", 72 | "filename" : "app-icon-76@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "83.5x83.5", 77 | "idiom" : "ipad", 78 | "filename" : "app-icon-83.5@2x.png", 79 | "scale" : "2x" 80 | } 81 | ], 82 | "info" : { 83 | "version" : 1, 84 | "author" : "xcode" 85 | } 86 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-29.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-29@2x-1.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-29@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-29@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-40.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-40@2x-1.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-40@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-40@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-60@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-60@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-76.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-76@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/AppIcon.appiconset/app-icon-83.5@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/amelia-walker.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "amelia-walker.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "amelia-walker@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/amelia-walker.imageset/amelia-walker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/amelia-walker.imageset/amelia-walker.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/amelia-walker.imageset/amelia-walker@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/amelia-walker.imageset/amelia-walker@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/diane-howell.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "diane-howell.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "diane-howell@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/diane-howell.imageset/diane-howell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/diane-howell.imageset/diane-howell.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/diane-howell.imageset/diane-howell@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/diane-howell.imageset/diane-howell@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/george-shelton.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "george-shelton.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "george-shelton@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/george-shelton.imageset/george-shelton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/george-shelton.imageset/george-shelton.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/george-shelton.imageset/george-shelton@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/george-shelton.imageset/george-shelton@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/julia-allen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "julia-allen.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "julia-allen@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/julia-allen.imageset/julia-allen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/julia-allen.imageset/julia-allen.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/julia-allen.imageset/julia-allen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/julia-allen.imageset/julia-allen@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/lauren-king.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "lauren-king.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "lauren-king@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/lauren-king.imageset/lauren-king.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/lauren-king.imageset/lauren-king.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/lauren-king.imageset/lauren-king@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/lauren-king.imageset/lauren-king@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/maria-garrett.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "maria-garrett.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "maria-garrett@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/maria-garrett.imageset/maria-garrett.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/maria-garrett.imageset/maria-garrett.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/maria-garrett.imageset/maria-garrett@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/maria-garrett.imageset/maria-garrett@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/matthew-fuller.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "matthew-fuller.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "matthew-fuller@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/matthew-fuller.imageset/matthew-fuller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/matthew-fuller.imageset/matthew-fuller.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/matthew-fuller.imageset/matthew-fuller@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/matthew-fuller.imageset/matthew-fuller@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/nicholas-palmer.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "nicholas-palmer.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "nicholas-palmer@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/nicholas-palmer.imageset/nicholas-palmer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/nicholas-palmer.imageset/nicholas-palmer.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/nicholas-palmer.imageset/nicholas-palmer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/nicholas-palmer.imageset/nicholas-palmer@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/stephanie-sharp.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "stephanie-sharp.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "stephanie-sharp@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "stephanie-sharp@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/stephanie-sharp.imageset/stephanie-sharp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/stephanie-sharp.imageset/stephanie-sharp.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/stephanie-sharp.imageset/stephanie-sharp@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/stephanie-sharp.imageset/stephanie-sharp@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/stephanie-sharp.imageset/stephanie-sharp@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/stephanie-sharp.imageset/stephanie-sharp@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/thomas-lynch.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "thomas-lynch.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "thomas-lynch@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/thomas-lynch.imageset/thomas-lynch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/thomas-lynch.imageset/thomas-lynch.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/thomas-lynch.imageset/thomas-lynch@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/thomas-lynch.imageset/thomas-lynch@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/vincent-greene.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "vincent-greene.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "vincent-greene@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/vincent-greene.imageset/vincent-greene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/vincent-greene.imageset/vincent-greene.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/People/vincent-greene.imageset/vincent-greene@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/People/vincent-greene.imageset/vincent-greene@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book-filled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "address-book-filled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "address-book-filled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "address-book-filled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book-filled.imageset/address-book-filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book-filled.imageset/address-book-filled.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book-filled.imageset/address-book-filled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book-filled.imageset/address-book-filled@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book-filled.imageset/address-book-filled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book-filled.imageset/address-book-filled@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "address-book.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "address-book@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "address-book@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book.imageset/address-book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book.imageset/address-book.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book.imageset/address-book@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book.imageset/address-book@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book.imageset/address-book@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/address-book.imageset/address-book@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/exit-filled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "exit-filled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "exit-filled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "exit-filled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/exit-filled.imageset/exit-filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/exit-filled.imageset/exit-filled.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/exit-filled.imageset/exit-filled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/exit-filled.imageset/exit-filled@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/exit-filled.imageset/exit-filled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/exit-filled.imageset/exit-filled@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/exit.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "exit.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "exit@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "exit@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/exit.imageset/exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/exit.imageset/exit.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/exit.imageset/exit@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/exit.imageset/exit@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/exit.imageset/exit@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/exit.imageset/exit@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/left-arrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "left-arrow.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "left-arrow@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "left-arrow@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/left-arrow.imageset/left-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/left-arrow.imageset/left-arrow.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/left-arrow.imageset/left-arrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/left-arrow.imageset/left-arrow@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/left-arrow.imageset/left-arrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/left-arrow.imageset/left-arrow@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/mail-filled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "mail-filled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "mail-filled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "mail-filled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/mail-filled.imageset/mail-filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/mail-filled.imageset/mail-filled.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/mail-filled.imageset/mail-filled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/mail-filled.imageset/mail-filled@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/mail-filled.imageset/mail-filled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/mail-filled.imageset/mail-filled@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/mail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "mail.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "mail@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "mail@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/mail.imageset/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/mail.imageset/mail.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/mail.imageset/mail@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/mail.imageset/mail@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/mail.imageset/mail@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/mail.imageset/mail@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/message-filled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "message-filled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "message-filled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "message-filled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/message-filled.imageset/message-filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/message-filled.imageset/message-filled.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/message-filled.imageset/message-filled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/message-filled.imageset/message-filled@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/message-filled.imageset/message-filled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/message-filled.imageset/message-filled@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/message.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "message.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "message@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "message@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/message.imageset/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/message.imageset/message.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/message.imageset/message@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/message.imageset/message@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/message.imageset/message@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/message.imageset/message@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/phone-filled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "phone-filled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "phone-filled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "phone-filled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/phone-filled.imageset/phone-filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/phone-filled.imageset/phone-filled.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/phone-filled.imageset/phone-filled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/phone-filled.imageset/phone-filled@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/phone-filled.imageset/phone-filled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/phone-filled.imageset/phone-filled@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/phone.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "phone.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "phone@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "phone@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/phone.imageset/phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/phone.imageset/phone.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/phone.imageset/phone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/phone.imageset/phone@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/phone.imageset/phone@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/phone.imageset/phone@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/star-filled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "star-filled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "star-filled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "star-filled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/star-filled.imageset/star-filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/star-filled.imageset/star-filled.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/star-filled.imageset/star-filled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/star-filled.imageset/star-filled@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/star-filled.imageset/star-filled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/star-filled.imageset/star-filled@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/star.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "star.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "star@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "star@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/star.imageset/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/star.imageset/star.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/star.imageset/star@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/star.imageset/star@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/star.imageset/star@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/star.imageset/star@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/stars-filled.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "stars-filled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "stars-filled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "stars-filled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/stars-filled.imageset/stars-filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/stars-filled.imageset/stars-filled.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/stars-filled.imageset/stars-filled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/stars-filled.imageset/stars-filled@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/stars-filled.imageset/stars-filled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/stars-filled.imageset/stars-filled@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/stars.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "stars.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "stars@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "stars@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/stars.imageset/stars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/stars.imageset/stars.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/stars.imageset/stars@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/stars.imageset/stars@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/Profile/stars.imageset/stars@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/Profile/stars.imageset/stars@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/launch-screen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "launch-screen.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "launch-screen@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "launch-screen@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/launch-screen.imageset/launch-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/launch-screen.imageset/launch-screen.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/launch-screen.imageset/launch-screen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/launch-screen.imageset/launch-screen@2x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Assets.xcassets/launch-screen.imageset/launch-screen@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephsharp/MaskZoomTransition/2d5d0e247f359e82544c2d851d898db711c1f1ea/MaskZoomTransitionDemo/Assets.xcassets/launch-screen.imageset/launch-screen@3x.png -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 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 | 121 | 122 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Categories/Navigation/UIView+MZNavigationBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MZNavigationBar.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (MZNavigationBar) 12 | 13 | - (void)mz_hideBottomHairlineAnimated:(BOOL)animated; 14 | - (void)mz_showBottomHairlineAnimated:(BOOL)animated; 15 | - (BOOL)mz_hairlineIsVisible; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Categories/Navigation/UIView+MZNavigationBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MZNavigationBar.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "UIView+MZNavigationBar.h" 10 | 11 | @implementation UIView (MZNavigationBar) 12 | 13 | static NSTimeInterval const MZDefaultDuration = 0.2; 14 | 15 | - (void)mz_hideBottomHairlineAnimated:(BOOL)animated 16 | { 17 | UIImageView *navigationBarImageView = [self mz_hairlineImageViewInNavigationBar]; 18 | NSTimeInterval duration = animated ? MZDefaultDuration : 0; 19 | 20 | [UIView animateWithDuration:duration animations:^{ 21 | navigationBarImageView.alpha = 0.0f; 22 | }]; 23 | } 24 | 25 | - (void)mz_showBottomHairlineAnimated:(BOOL)animated 26 | { 27 | UIImageView *navigationBarImageView = [self mz_hairlineImageViewInNavigationBar]; 28 | NSTimeInterval duration = animated ? MZDefaultDuration : 0; 29 | 30 | [UIView animateWithDuration:duration animations:^{ 31 | navigationBarImageView.alpha = 1.0f; 32 | }]; 33 | } 34 | 35 | - (BOOL)mz_hairlineIsVisible 36 | { 37 | UIImageView *navigationBarImageView = [self mz_hairlineImageViewInNavigationBar]; 38 | return (navigationBarImageView.alpha > 0.0f); 39 | } 40 | 41 | - (UIImageView *)mz_hairlineImageViewInNavigationBar 42 | { 43 | if ([self isKindOfClass:UIImageView.class] && self.bounds.size.height <= 1.0) { 44 | return (UIImageView *)self; 45 | } 46 | for (UIView *subview in self.subviews) { 47 | UIImageView *imageView = [subview mz_hairlineImageViewInNavigationBar]; 48 | if (imageView) { 49 | return imageView; 50 | } 51 | } 52 | return nil; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Categories/View Containment/UIView+MZEmbed.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MZEmbed.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (MZEmbed) 12 | 13 | - (void)mz_addContainerConstraintsToSubview:(UIView *)subview; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Categories/View Containment/UIView+MZEmbed.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+MZEmbed.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "UIView+MZEmbed.h" 10 | 11 | @implementation UIView (MZEmbed) 12 | 13 | - (void)mz_addContainerConstraintsToSubview:(UIView *)subview 14 | { 15 | subview.translatesAutoresizingMaskIntoConstraints = NO; 16 | 17 | NSDictionary *views = NSDictionaryOfVariableBindings(subview); 18 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subview]|" 19 | options:0 20 | metrics:nil 21 | views:views]]; 22 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview]|" 23 | options:0 24 | metrics:nil 25 | views:views]]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Colors/View Controllers/MZColorViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZColorViewController.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MZMaskZoomTransitioningDelegate.h" 11 | 12 | @interface MZColorViewController : UIViewController 13 | 14 | @property (nonatomic) UIColor *circleColor; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Colors/View Controllers/MZColorViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZColorViewController.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZColorViewController.h" 10 | #import "MZTheme.h" 11 | #import "UIView+MZNavigationBar.h" 12 | 13 | @interface MZColorViewController () 14 | 15 | @property (weak, nonatomic) IBOutlet UIView *circleView; 16 | @property (weak, nonatomic) IBOutlet UILabel *colorLabelRGB; 17 | @property (weak, nonatomic) IBOutlet UILabel *colorLabelHSB; 18 | @property (weak, nonatomic) IBOutlet UILabel *colorLabelHex; 19 | 20 | @end 21 | 22 | @implementation MZColorViewController 23 | 24 | - (void)viewDidLoad 25 | { 26 | [super viewDidLoad]; 27 | 28 | self.circleView.backgroundColor = self.circleColor; 29 | [self setColorLabels]; 30 | 31 | self.navigationItem.leftBarButtonItem.tintColor = self.circleColor; 32 | [self.navigationController.navigationBar mz_hideBottomHairlineAnimated:NO]; 33 | } 34 | 35 | - (void)viewDidAppear:(BOOL)animated 36 | { 37 | [super viewDidAppear:animated]; 38 | 39 | [MZTheme setGlobalTintColor:self.circleColor]; 40 | } 41 | 42 | - (void)setColorLabels 43 | { 44 | CGFloat r = 0.0, g = 0.0, b = 0.0; 45 | CGFloat h = 0.0, s = 0.0, br = 0.0; 46 | [self.circleColor getRed:&r green:&g blue:&b alpha:NULL]; 47 | [self.circleColor getHue:&h saturation:&s brightness:&br alpha:NULL]; 48 | 49 | int red = r * 255, green = g * 255, blue = b * 255; 50 | int hue = h * 100, saturation = s * 100, brightness = br * 100; 51 | 52 | self.colorLabelRGB.text = [NSString stringWithFormat:@"R:%d G:%d B:%d", red, green, blue]; 53 | self.colorLabelHSB.text = [NSString stringWithFormat:@"H:%d S:%d B:%d", hue, saturation, brightness]; 54 | self.colorLabelHex.text = [NSString stringWithFormat:@"#%02X%02X%02X", red, green, blue]; 55 | } 56 | 57 | #pragma mark - Actions 58 | 59 | - (IBAction)dismiss 60 | { 61 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 62 | } 63 | 64 | #pragma mark - MZMaskZoomTransitionPresentedViewController 65 | 66 | @synthesize largeView, viewsToFadeIn; 67 | 68 | - (NSArray *)viewsToFadeIn 69 | { 70 | return @[self.colorLabelRGB, self.colorLabelHSB, self.colorLabelHex]; 71 | } 72 | 73 | - (UIView *)largeView 74 | { 75 | return self.circleView; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Colors/View Controllers/MZColorsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZColorsViewController.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZColorsViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Colors/View Controllers/MZColorsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZColorsViewController.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZColorsViewController.h" 10 | #import "MZMaskZoomTransitioningDelegate.h" 11 | #import "MZColorViewController.h" 12 | #import "UIViewController+MZContentViewController.h" 13 | 14 | @interface MZColorsViewController () 15 | 16 | @property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *circleButtons; 17 | @property (nonatomic) MZMaskZoomTransitioningDelegate *transitioningDelegate; 18 | 19 | @end 20 | 21 | @implementation MZColorsViewController 22 | 23 | #pragma mark - Properties 24 | 25 | - (MZMaskZoomTransitioningDelegate *)transitioningDelegate 26 | { 27 | if (!_transitioningDelegate) { 28 | _transitioningDelegate = [MZMaskZoomTransitioningDelegate new]; 29 | } 30 | return _transitioningDelegate; 31 | } 32 | 33 | #pragma mark - Actions 34 | 35 | - (IBAction)buttonTap:(id)sender 36 | { 37 | [self performSegueWithIdentifier:@"MaskZoomSegue" sender:sender]; 38 | } 39 | 40 | - (IBAction)pop 41 | { 42 | [self.navigationController popViewControllerAnimated:YES]; 43 | } 44 | 45 | #pragma mark - Navigation 46 | 47 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 48 | { 49 | if ([[segue identifier] isEqualToString:@"MaskZoomSegue"]) { 50 | MZColorViewController *colorVC = (MZColorViewController *)segue.destinationViewController.mz_contentViewController; 51 | UIButton *button = (UIButton *)sender; 52 | 53 | colorVC.circleColor = button.backgroundColor; 54 | self.transitioningDelegate.smallView = button; 55 | 56 | segue.destinationViewController.transitioningDelegate = self.transitioningDelegate; 57 | segue.destinationViewController.modalPresentationStyle = UIModalPresentationCustom; 58 | } 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Colors/Views/MZCircleButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZCircleButton.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 18/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | IB_DESIGNABLE 12 | @interface MZCircleButton : UIButton 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Colors/Views/MZCircleButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZCircleButton.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 18/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZCircleButton.h" 10 | 11 | @implementation MZCircleButton 12 | 13 | - (instancetype)initWithCoder:(NSCoder *)coder 14 | { 15 | self = [super initWithCoder:coder]; 16 | if (self) { 17 | [self sharedInit]; 18 | } 19 | return self; 20 | } 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | [self sharedInit]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)sharedInit 32 | { 33 | self.layer.cornerRadius = CGRectGetMidX(self.bounds); 34 | self.layer.masksToBounds = YES; 35 | } 36 | 37 | - (void)layoutSubviews 38 | { 39 | [super layoutSubviews]; 40 | self.layer.cornerRadius = CGRectGetMidX(self.bounds); 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Colors/Views/MZCircleView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZCircleView.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | IB_DESIGNABLE 12 | @interface MZCircleView : UIView 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Colors/Views/MZCircleView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZCircleView.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZCircleView.h" 10 | 11 | @implementation MZCircleView 12 | 13 | - (instancetype)initWithCoder:(NSCoder *)coder 14 | { 15 | self = [super initWithCoder:coder]; 16 | if (self) { 17 | [self sharedInit]; 18 | } 19 | return self; 20 | } 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | [self sharedInit]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)sharedInit 32 | { 33 | self.layer.cornerRadius = CGRectGetMidX(self.bounds); 34 | self.layer.masksToBounds = YES; 35 | } 36 | 37 | - (void)layoutSubviews 38 | { 39 | [super layoutSubviews]; 40 | self.layer.cornerRadius = CGRectGetMidX(self.bounds); 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/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 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Controllers/MZProfilesController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfilesController.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 21/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MZProfile.h" 11 | 12 | @interface MZProfilesController : NSObject 13 | 14 | @property (nonatomic, readonly) NSArray *profiles; /* of MZProfile */ 15 | @property (nonatomic, readonly) MZProfile *authenticatedUser; 16 | 17 | - (void)deleteProfile:(MZProfile *)profile; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Controllers/MZProfilesController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfilesController.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 21/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZProfilesController.h" 10 | #import "MZPersonStore.h" 11 | 12 | @interface MZProfilesController () 13 | 14 | @property (nonatomic, readwrite) NSArray *profiles; 15 | @property (nonatomic, readwrite) MZProfile *authenticatedUser; 16 | 17 | @end 18 | 19 | @implementation MZProfilesController 20 | 21 | - (instancetype)init 22 | { 23 | self = [super init]; 24 | if (self) { 25 | _profiles = [self createProfiles]; 26 | } 27 | return self; 28 | } 29 | 30 | - (NSArray *)createProfiles 31 | { 32 | MZPersonStore *store = [MZPersonStore new]; 33 | NSMutableArray *profiles = [NSMutableArray array]; 34 | 35 | for (MZPerson *person in store.people) { 36 | MZProfile *profile = [[MZProfile alloc] initWithPerson:person]; 37 | 38 | if (person.isAuthenticated && !self.authenticatedUser) { 39 | self.authenticatedUser = profile; 40 | } 41 | else { 42 | [profiles addObject:profile]; 43 | } 44 | } 45 | return [profiles copy]; 46 | } 47 | 48 | - (void)deleteProfile:(MZProfile *)profile 49 | { 50 | NSMutableArray *mutableProfiles = [self.profiles mutableCopy]; 51 | [mutableProfiles removeObject:profile]; 52 | self.profiles = [mutableProfiles copy]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Data Store/MZPeople.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | firstName 7 | Stephanie 8 | lastName 9 | Sharp 10 | role 11 | Mobile Engineer 12 | location 13 | Melbourne 14 | department 15 | Digital 16 | email 17 | ssharp@example.com 18 | mobile 19 | 0434 838 787 20 | phone 21 | 03 9472 7356 22 | profileImage 23 | stephanie-sharp 24 | authenticated 25 | 26 | 27 | 28 | firstName 29 | Amelia 30 | lastName 31 | Walker 32 | role 33 | Project Manager 34 | location 35 | Sydney 36 | department 37 | Delivery 38 | email 39 | awalker@example.com 40 | mobile 41 | 0488 777 832 42 | phone 43 | 02 7347 5555 44 | profileImage 45 | amelia-walker 46 | 47 | 48 | firstName 49 | Diane 50 | lastName 51 | Howell 52 | role 53 | CEO 54 | location 55 | Sydney 56 | department 57 | 58 | email 59 | dhowell@example.com 60 | mobile 61 | 0472 275 742 62 | phone 63 | 02 6743 5730 64 | profileImage 65 | diane-howell 66 | 67 | 68 | firstName 69 | George 70 | lastName 71 | Shelton 72 | role 73 | Delivery Lead 74 | location 75 | Melbourne 76 | department 77 | Digital 78 | email 79 | gshelton@example.com 80 | mobile 81 | 0428 737 626 82 | phone 83 | 03 9843 8785 84 | profileImage 85 | george-shelton 86 | 87 | 88 | firstName 89 | Julia 90 | lastName 91 | Allen 92 | role 93 | Software Engineer 94 | location 95 | Sydney 96 | department 97 | Digital 98 | email 99 | jallen@example.com 100 | mobile 101 | 0486 033 688 102 | phone 103 | 104 | profileImage 105 | julia-allen 106 | 107 | 108 | firstName 109 | Justin 110 | lastName 111 | Crawford 112 | role 113 | Tech Lead 114 | location 115 | Brisbane 116 | department 117 | 118 | email 119 | jcrawford@example.com 120 | mobile 121 | 0464 9392 5732 122 | phone 123 | 07 8372 7622 124 | profileImage 125 | 126 | 127 | 128 | firstName 129 | Lauren 130 | lastName 131 | King 132 | role 133 | Mobile Engineer 134 | location 135 | Sydney 136 | department 137 | Digital 138 | email 139 | lking@example.com 140 | mobile 141 | 0476 732 125 142 | phone 143 | 144 | profileImage 145 | lauren-king 146 | 147 | 148 | firstName 149 | Liam 150 | lastName 151 | Williams 152 | role 153 | Software Engineer 154 | location 155 | Brisbane 156 | department 157 | Digital 158 | email 159 | lwilliams@example.com 160 | mobile 161 | 0438 826 644 162 | phone 163 | 164 | profileImage 165 | 166 | 167 | 168 | firstName 169 | Lisa 170 | lastName 171 | Mills 172 | role 173 | Front End Engineer 174 | location 175 | Melbourne 176 | department 177 | Digital 178 | email 179 | lmills@example.com 180 | mobile 181 | 0483 374 473 182 | phone 183 | 03 8573 6126 184 | profileImage 185 | 186 | 187 | 188 | firstName 189 | Maria 190 | lastName 191 | Garrett 192 | role 193 | Senior Software Engineer 194 | location 195 | Melbourne 196 | department 197 | Delivery 198 | email 199 | mgarrett@example.com 200 | mobile 201 | 0483 723 912 202 | phone 203 | 204 | profileImage 205 | maria-garrett 206 | 207 | 208 | firstName 209 | Matthew 210 | lastName 211 | Fuller 212 | role 213 | Visual Designer 214 | location 215 | Sydney 216 | department 217 | Delivery 218 | email 219 | mfuller@example.com 220 | mobile 221 | 0476 703 395 222 | phone 223 | 02 8464 7362 224 | profileImage 225 | matthew-fuller 226 | 227 | 228 | firstName 229 | Nicholas 230 | lastName 231 | Palmer 232 | role 233 | Recruiter 234 | location 235 | Melbourne 236 | department 237 | People & Culture 238 | email 239 | npalmer@example.com 240 | mobile 241 | 0496 436 957 242 | phone 243 | 03 8536 2652 244 | profileImage 245 | nicholas-palmer 246 | 247 | 248 | firstName 249 | Thomas 250 | lastName 251 | Lynch 252 | role 253 | Software Engineer 254 | location 255 | Melbourne 256 | department 257 | Digital 258 | email 259 | tlynch@example.com 260 | mobile 261 | 0484 836 964 262 | phone 263 | 264 | profileImage 265 | thomas-lynch 266 | 267 | 268 | firstName 269 | Vincent 270 | lastName 271 | Greene 272 | role 273 | Business Analyst 274 | location 275 | Brisbane 276 | department 277 | 278 | email 279 | vgreene@example.com 280 | mobile 281 | 0484 836 964 282 | phone 283 | 284 | profileImage 285 | vincent-greene 286 | 287 | 288 | 289 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Data Store/MZPersonStore.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZPersonStore.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MZPerson.h" 11 | 12 | @interface MZPersonStore : NSObject 13 | 14 | @property (nonatomic, readonly) NSArray *people; /* of MZPerson */ 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Data Store/MZPersonStore.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZPersonStore.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZPersonStore.h" 10 | 11 | @implementation MZPersonStore 12 | 13 | - (instancetype)init 14 | { 15 | self = [super init]; 16 | if (self) { 17 | _people = [self peopleFromPlist]; 18 | } 19 | return self; 20 | } 21 | - (NSArray *)peopleFromPlist 22 | { 23 | NSMutableArray *people = [NSMutableArray array]; 24 | 25 | NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"MZPeople" ofType:@"plist"]; 26 | NSArray *peopleData = [NSArray arrayWithContentsOfFile:plistPath]; 27 | 28 | for (NSDictionary *p in peopleData) { 29 | [people addObject:[[MZPerson alloc] initWithFirstName:p[@"firstName"] 30 | lastName:p[@"lastName"] 31 | role:p[@"role"] 32 | location:p[@"location"] 33 | department:p[@"department"] 34 | email:p[@"email"] 35 | mobile:p[@"mobile"] 36 | phone:p[@"phone"] 37 | profileImageName:p[@"profileImage"] 38 | authenticated:[p[@"authenticated"] boolValue]]]; 39 | } 40 | 41 | return [people copy]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Models/MZPerson.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZPerson.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZPerson : NSObject 12 | 13 | @property (nonatomic) NSString *firstName; 14 | @property (nonatomic) NSString *lastName; 15 | @property (nonatomic) NSString *role; 16 | @property (nonatomic) NSString *location; 17 | @property (nonatomic) NSString *department; 18 | @property (nonatomic) NSString *email; 19 | @property (nonatomic) NSString *mobile; 20 | @property (nonatomic) NSString *phone; 21 | @property (nonatomic) NSString *profileImageName; 22 | @property (nonatomic, getter=isAuthenticated) BOOL authenticated; 23 | 24 | - (instancetype)initWithFirstName:(NSString *)firstName 25 | lastName:(NSString *)lastName 26 | role:(NSString *)role 27 | location:(NSString *)location 28 | department:(NSString *)department 29 | email:(NSString *)email 30 | mobile:(NSString *)mobile 31 | phone:(NSString *)phone 32 | profileImageName:(NSString *)profileImageName 33 | authenticated:(BOOL)authenticated NS_DESIGNATED_INITIALIZER; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Models/MZPerson.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZPerson.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZPerson.h" 10 | 11 | @implementation MZPerson 12 | 13 | - (instancetype)initWithFirstName:(NSString *)firstName 14 | lastName:(NSString *)lastName 15 | role:(NSString *)role 16 | location:(NSString *)location 17 | department:(NSString *)department 18 | email:(NSString *)email 19 | mobile:(NSString *)mobile 20 | phone:(NSString *)phone 21 | profileImageName:(NSString *)profileImageName 22 | authenticated:(BOOL)authenticated 23 | { 24 | self = [super init]; 25 | if (self) { 26 | _firstName = firstName; 27 | _lastName = lastName; 28 | _role = role; 29 | _location = location; 30 | _department = department; 31 | _email = email; 32 | _mobile = mobile; 33 | _phone = phone; 34 | _profileImageName = profileImageName; 35 | _authenticated = authenticated; 36 | } 37 | return self; 38 | } 39 | 40 | - (instancetype)init 41 | { 42 | return [self initWithFirstName:nil lastName:nil role:nil location:nil department:nil email:nil mobile:nil phone:nil profileImageName:nil authenticated:NO]; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Models/MZProfile.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfile.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MZPerson.h" 11 | 12 | @interface MZProfile : NSObject 13 | 14 | @property (nonatomic, readonly) MZPerson *person; 15 | 16 | @property (nonatomic, readonly) NSString *displayName; 17 | @property (nonatomic, readonly) NSString *initials; 18 | @property (nonatomic, readonly) UIImage *profileImage; 19 | 20 | - (instancetype)initWithPerson:(MZPerson *)person; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Models/MZProfile.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfile.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZProfile.h" 10 | #import "NSString+MZProfile.h" 11 | #import "MZProfileCell.h" 12 | 13 | static NSString *const MZMobileTitle = @"mobile"; 14 | static NSString *const MZPhoneTitle = @"work"; 15 | static NSString *const MZEmailTitle = @"email"; 16 | static NSString *const MZDepartmentTitle = @"department"; 17 | static NSUInteger const MZProfileImageSize = 450; 18 | 19 | @interface MZProfile () 20 | 21 | @property (nonatomic) NSArray *tableData; 22 | 23 | @end 24 | 25 | @implementation MZProfile 26 | 27 | - (instancetype)initWithPerson:(MZPerson *)person 28 | { 29 | self = [super init]; 30 | if (self) { 31 | _person = person; 32 | } 33 | return self; 34 | } 35 | 36 | - (instancetype)init 37 | { 38 | return [self initWithPerson:nil]; 39 | } 40 | 41 | - (NSString *)displayName 42 | { 43 | return [NSString stringWithFormat:@"%@ %@", self.person.firstName, self.person.lastName]; 44 | } 45 | 46 | - (NSString *)initials 47 | { 48 | return [NSString stringWithFormat:@"%@%@", [self.person.firstName mz_uppercaseInitial], [self.person.lastName mz_uppercaseInitial]]; 49 | } 50 | 51 | - (UIImage *)profileImage 52 | { 53 | UIImage *image; 54 | 55 | if (self.person.profileImageName.length > 0) { 56 | image = [UIImage imageNamed:self.person.profileImageName]; 57 | } 58 | 59 | return image ?: [self.initials mz_placeholderImageFromStringWithSize:MZProfileImageSize]; 60 | } 61 | 62 | - (NSArray *)tableData 63 | { 64 | if (!_tableData) { 65 | NSMutableArray *mutableTableData = [NSMutableArray new]; 66 | 67 | if (self.person.mobile.length > 0) { 68 | [mutableTableData addObject:@{ @"title" : MZMobileTitle, @"content" : self.person.mobile }]; 69 | } 70 | 71 | if (self.person.phone.length > 0) { 72 | [mutableTableData addObject:@{ @"title" : MZPhoneTitle, @"content" : self.person.phone }]; 73 | } 74 | 75 | if (self.person.email.length > 0) { 76 | [mutableTableData addObject:@{ @"title" : MZEmailTitle, @"content" : self.person.email }]; 77 | } 78 | 79 | if (self.person.department.length > 0) { 80 | [mutableTableData addObject:@{ @"title" : MZDepartmentTitle, @"content" : self.person.department }]; 81 | } 82 | 83 | _tableData = [mutableTableData copy]; 84 | } 85 | return _tableData; 86 | } 87 | 88 | #pragma mark - UITableViewDataSource 89 | 90 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 91 | { 92 | return 1; 93 | } 94 | 95 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 96 | { 97 | return (NSInteger)self.tableData.count; 98 | } 99 | 100 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 101 | { 102 | MZProfileCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ProfileCell"]; 103 | 104 | NSUInteger index = (NSUInteger)indexPath.row; 105 | cell.titleLabel.text = self.tableData[index][@"title"]; 106 | cell.contentLabel.text = self.tableData[index][@"content"]; 107 | 108 | return cell; 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Models/NSString+MZProfile.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+MZProfile.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (MZProfile) 12 | 13 | - (NSString *)mz_uppercaseInitial; 14 | - (UIImage *)mz_placeholderImageFromStringWithSize:(CGFloat)size; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Models/NSString+MZProfile.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+MZProfile.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "NSString+MZProfile.h" 10 | #import "MZTheme.h" 11 | 12 | @implementation NSString (MZProfile) 13 | 14 | - (NSString *)mz_uppercaseInitial 15 | { 16 | if (self.length > 0) { 17 | return [[self substringToIndex:1] uppercaseString]; 18 | } 19 | 20 | return @""; 21 | } 22 | 23 | - (UIImage *)mz_placeholderImageFromStringWithSize:(CGFloat)size 24 | { 25 | CGRect rect = CGRectMake(0, 0, size, size); 26 | 27 | UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0f); 28 | 29 | // Set background color 30 | [[MZTheme globalTintColor] setFill]; 31 | UIRectFill(rect); 32 | 33 | // Set the font style and size 34 | NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; 35 | [style setAlignment:NSTextAlignmentCenter]; 36 | 37 | CGFloat fontSize = size / 2.4f; 38 | UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:fontSize]; 39 | NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys: 40 | [UIColor whiteColor], NSForegroundColorAttributeName, 41 | font, NSFontAttributeName, 42 | style, NSParagraphStyleAttributeName, nil]; 43 | 44 | CGFloat verticalOffset = CGRectGetMidY(rect) - (font.lineHeight / 2.0f); 45 | rect.origin.y = verticalOffset; 46 | 47 | [self drawInRect:rect withAttributes:attr]; 48 | 49 | // Get image 50 | CGContextSetAllowsAntialiasing(UIGraphicsGetCurrentContext(), YES); 51 | CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), YES); 52 | 53 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 54 | 55 | UIGraphicsEndImageContext(); 56 | 57 | return image; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/View Controllers/MZPeopleTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZPeopleTableViewController.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZPeopleTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/View Controllers/MZPeopleTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZPeopleTableViewController.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZPeopleTableViewController.h" 10 | #import "MZProfilesController.h" 11 | #import "MZPersonCell.h" 12 | #import "UIViewController+MZContentViewController.h" 13 | #import "MZProfileViewController.h" 14 | #import "MZProfileButton.h" 15 | 16 | @interface MZPeopleTableViewController () 17 | 18 | @property (nonatomic) MZProfilesController *profilesController; 19 | @property (nonatomic) MZMaskZoomTransitioningDelegate * transitioningDelegate; 20 | @property (nonatomic) MZProfileButton *myProfileButton; 21 | 22 | @end 23 | 24 | @implementation MZPeopleTableViewController 25 | 26 | - (void)viewDidLoad 27 | { 28 | [super viewDidLoad]; 29 | 30 | self.profilesController = [MZProfilesController new]; 31 | self.transitioningDelegate = [MZMaskZoomTransitioningDelegate new]; 32 | 33 | if (self.profilesController.authenticatedUser) { 34 | [self addProfileButtonToNavigationBar]; 35 | } 36 | } 37 | 38 | #pragma mark - UITableViewDataSource 39 | 40 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 41 | { 42 | return 1; 43 | } 44 | 45 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 46 | { 47 | return self.profilesController.profiles.count; 48 | } 49 | 50 | 51 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 52 | { 53 | MZPersonCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PersonCell" forIndexPath:indexPath]; 54 | MZProfile *profile = self.profilesController.profiles[indexPath.row]; 55 | 56 | cell.nameLabel.text = profile.displayName; 57 | cell.roleLabel.text = profile.person.role; 58 | cell.avatarImageView.image = profile.profileImage; 59 | 60 | return cell; 61 | } 62 | 63 | 64 | #pragma mark - UITableViewDelegate 65 | 66 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 67 | { 68 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 69 | } 70 | 71 | #pragma mark - Navigation 72 | 73 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 74 | { 75 | UIViewController *contentViewController = segue.destinationViewController.mz_contentViewController; 76 | 77 | if ([[segue identifier] isEqualToString:@"ProfileSegue"]) { 78 | MZProfileViewController *profileVC = (MZProfileViewController *)contentViewController; 79 | profileVC.delegate = self; 80 | 81 | if ([sender isKindOfClass:[MZPersonCell class]]) { 82 | MZPersonCell *cell = (MZPersonCell *)sender; 83 | self.transitioningDelegate.smallView = cell.avatarImageView; 84 | 85 | NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; 86 | profileVC.profile = self.profilesController.profiles[indexPath.row]; 87 | } 88 | else if ([sender isEqual:self.myProfileButton]) { 89 | self.transitioningDelegate.smallView = self.myProfileButton; 90 | profileVC.profile = self.profilesController.authenticatedUser; 91 | } 92 | 93 | segue.destinationViewController.transitioningDelegate = self.transitioningDelegate; 94 | segue.destinationViewController.modalPresentationStyle = UIModalPresentationCustom; 95 | } 96 | } 97 | 98 | - (void)addProfileButtonToNavigationBar 99 | { 100 | self.myProfileButton = [[MZProfileButton alloc] initWithProfile:self.profilesController.authenticatedUser]; 101 | [self.myProfileButton addTarget:self action:@selector(profilePressed:) forControlEvents:UIControlEventTouchUpInside]; 102 | 103 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.myProfileButton]; 104 | } 105 | 106 | #pragma mark - Actions 107 | 108 | - (IBAction)pop 109 | { 110 | [self.navigationController popViewControllerAnimated:YES]; 111 | } 112 | 113 | - (IBAction)profilePressed:(UIButton *)sender 114 | { 115 | [self performSegueWithIdentifier:@"ProfileSegue" sender:sender]; 116 | } 117 | 118 | #pragma mark - MZProfileViewControllerDelegate 119 | 120 | - (void)MZProfileViewControllerShouldDelete:(MZProfileViewController *)profileViewController 121 | { 122 | [self.profilesController deleteProfile:profileViewController.profile]; 123 | [self.tableView reloadData]; 124 | self.transitioningDelegate.dismissToZeroSize = YES; 125 | 126 | [self dismissViewControllerAnimated:YES completion:^{ 127 | // Set dismissToZeroSize back to NO after transition completes. 128 | self.transitioningDelegate.dismissToZeroSize = NO; 129 | }]; 130 | } 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/View Controllers/MZProfileViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfileViewController.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MZProfile.h" 11 | #import "MZMaskZoomTransitioningDelegate.h" 12 | 13 | @class MZProfileViewController; 14 | 15 | @protocol MZProfileViewControllerDelegate 16 | 17 | @optional 18 | - (void)MZProfileViewControllerShouldDismiss:(MZProfileViewController *)profileViewController; 19 | - (void)MZProfileViewControllerShouldDelete:(MZProfileViewController *)profileViewController; 20 | 21 | @end 22 | 23 | @interface MZProfileViewController : UIViewController 24 | 25 | @property (nonatomic, weak) id delegate; 26 | 27 | @property (nonatomic) MZProfile *profile; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/View Controllers/MZProfileViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfileViewController.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZProfileViewController.h" 10 | #import "UIView+MZEmbed.h" 11 | #import "UIView+MZNavigationBar.h" 12 | 13 | static CGFloat const MZProfileImageMinHeight = 80.0f; 14 | static CGFloat MZProfileImageMaxHeight; 15 | 16 | @interface MZProfileViewController () 17 | 18 | @property (weak, nonatomic) IBOutlet UIView *headerView; 19 | @property (weak, nonatomic) IBOutlet UIImageView *profileImageView; 20 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *profileImageViewHeightConstraint; 21 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 22 | @property (weak, nonatomic) IBOutlet UILabel *roleLabel; 23 | @property (weak, nonatomic) IBOutlet UILabel *locationLabel; 24 | 25 | @property (weak, nonatomic) IBOutlet UIView *profileButtonsContainerView; 26 | @property (weak, nonatomic) IBOutlet UITableView *contactDetailsTableView; 27 | 28 | @property (weak, nonatomic) IBOutlet UIView *profileButtonsView; 29 | @property (weak, nonatomic) IBOutlet UIButton *phoneButton; 30 | @property (weak, nonatomic) IBOutlet UIView *phoneSpacerView; 31 | @property (weak, nonatomic) IBOutlet UIButton *messageButton; 32 | @property (weak, nonatomic) IBOutlet UIView *messageSpacerView; 33 | @property (weak, nonatomic) IBOutlet UIButton *favouriteButton; 34 | @property (weak, nonatomic) IBOutlet UIButton *addressBookButton; 35 | 36 | @property (weak, nonatomic) IBOutlet UIView *myProfileButtonsView; 37 | @property (weak, nonatomic) IBOutlet UIButton *myAddressBookButton; 38 | 39 | @property (nonatomic) CGFloat profileImageOriginalHeight; 40 | 41 | @end 42 | 43 | @implementation MZProfileViewController 44 | 45 | @synthesize largeView, viewsToFadeIn; 46 | 47 | - (void)viewDidLoad 48 | { 49 | [super viewDidLoad]; 50 | 51 | MZProfileImageMaxHeight = CGRectGetWidth([UIScreen mainScreen].bounds) - 40.0f; 52 | 53 | // Decrease size of profile image on small screens (e.g. iPhone 4S) 54 | if (CGRectGetHeight([UIScreen mainScreen].bounds) < 568) { 55 | self.profileImageViewHeightConstraint.constant -= 35.0f; 56 | } 57 | 58 | [self setUpProfile]; 59 | [self addTableViewPanGestureRecognizerToView]; 60 | [self setupProfileButtons]; 61 | 62 | // When view is first loaded, hide navigation bar hairline immediately 63 | [self.navigationController.navigationBar mz_hideBottomHairlineAnimated:NO]; 64 | } 65 | 66 | - (void)viewWillAppear:(BOOL)animated 67 | { 68 | [super viewWillAppear:animated]; 69 | 70 | // When returning to this view (e.g. unwind), animate out the navigation bar hairline 71 | if ([self.navigationController.navigationBar mz_hairlineIsVisible]) { 72 | [self.navigationController.navigationBar mz_hideBottomHairlineAnimated:YES]; 73 | } 74 | } 75 | 76 | - (void)viewDidLayoutSubviews 77 | { 78 | [super viewDidLayoutSubviews]; 79 | [self setupTableView]; 80 | } 81 | 82 | - (void)setUpProfile 83 | { 84 | self.nameLabel.text = self.profile.displayName; 85 | self.roleLabel.text = self.profile.person.role; 86 | self.locationLabel.text = self.profile.person.location; 87 | self.profileImageView.image = self.profile.profileImage; 88 | 89 | self.contactDetailsTableView.dataSource = self.profile; 90 | 91 | // Hide delete button if viewing authenticated user 92 | if (self.profile.person.isAuthenticated) { 93 | self.navigationItem.rightBarButtonItem = nil; 94 | } 95 | } 96 | 97 | - (void)addTableViewPanGestureRecognizerToView 98 | { 99 | for (UIGestureRecognizer *recognizer in self.contactDetailsTableView.gestureRecognizers) { 100 | if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) { 101 | [self.view addGestureRecognizer:recognizer]; 102 | } 103 | } 104 | } 105 | 106 | - (void)setupTableView 107 | { 108 | if (self.contactDetailsTableView.contentInset.top == 0) { 109 | CGFloat topInset = CGRectGetHeight(self.headerView.frame) + 20; 110 | self.contactDetailsTableView.contentInset = UIEdgeInsetsMake(topInset, 0, 0, 0); 111 | } 112 | } 113 | 114 | - (void)setupProfileButtons 115 | { 116 | UIView *profileButtonsView = self.profile.person.isAuthenticated ? self.myProfileButtonsView : self.profileButtonsView; 117 | [self.profileButtonsContainerView addSubview:profileButtonsView]; 118 | [self.profileButtonsContainerView mz_addContainerConstraintsToSubview:profileButtonsView]; 119 | } 120 | 121 | #pragma mark - Properties 122 | 123 | - (CGFloat)profileImageOriginalHeight 124 | { 125 | if (_profileImageOriginalHeight == 0) { 126 | _profileImageOriginalHeight = self.profileImageViewHeightConstraint.constant; 127 | } 128 | return _profileImageOriginalHeight; 129 | } 130 | 131 | #pragma mark - UITableViewDelegate 132 | 133 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 134 | { 135 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 136 | } 137 | 138 | #pragma mark - UIScrollViewDelegate 139 | 140 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 141 | { 142 | CGFloat offset = scrollView.contentOffset.y + scrollView.contentInset.top; 143 | float imageHeight = fmaxf((float)(self.profileImageOriginalHeight - offset), (float)MZProfileImageMinHeight); 144 | imageHeight = fminf(imageHeight, (float)MZProfileImageMaxHeight); 145 | 146 | self.profileImageViewHeightConstraint.constant = imageHeight; 147 | } 148 | 149 | #pragma mark - MZMaskZoomTransitionPresentedViewController 150 | 151 | - (NSArray *)viewsToFadeIn 152 | { 153 | return @[self.nameLabel, 154 | self.roleLabel, 155 | self.locationLabel, 156 | self.profileButtonsContainerView, 157 | self.contactDetailsTableView]; 158 | } 159 | 160 | - (UIView *)largeView 161 | { 162 | return self.profileImageView; 163 | } 164 | 165 | #pragma mark - Actions 166 | 167 | - (IBAction)dismiss 168 | { 169 | if ([self.delegate respondsToSelector:@selector(MZProfileViewControllerShouldDismiss:)]) { 170 | [self.delegate MZProfileViewControllerShouldDismiss:self]; 171 | } 172 | else { 173 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 174 | } 175 | } 176 | 177 | - (IBAction)delete 178 | { 179 | NSString *title = [NSString stringWithFormat:@"Delete %@?", self.profile.person.firstName]; 180 | UIAlertController *deleteAlert = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert]; 181 | 182 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; 183 | UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { 184 | if ([self.delegate respondsToSelector:@selector(MZProfileViewControllerShouldDelete:)]) { 185 | [self.delegate MZProfileViewControllerShouldDelete:self]; 186 | [self dismiss]; 187 | } 188 | }]; 189 | 190 | [deleteAlert addAction:cancelAction]; 191 | [deleteAlert addAction:deleteAction]; 192 | 193 | [self presentViewController:deleteAlert animated:YES completion:nil]; 194 | } 195 | 196 | @end 197 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZCircleImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZCircleImageView.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZCircleImageView : UIImageView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZCircleImageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZCircleImageView.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZCircleImageView.h" 10 | 11 | @implementation MZCircleImageView 12 | 13 | - (instancetype)initWithCoder:(NSCoder *)coder 14 | { 15 | self = [super initWithCoder:coder]; 16 | if (self) { 17 | [self sharedInit]; 18 | } 19 | return self; 20 | } 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | [self sharedInit]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)sharedInit 32 | { 33 | self.layer.cornerRadius = CGRectGetMidX(self.bounds); 34 | self.layer.masksToBounds = YES; 35 | } 36 | 37 | - (void)layoutSubviews 38 | { 39 | [super layoutSubviews]; 40 | self.layer.cornerRadius = CGRectGetMidX(self.bounds); 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZLineView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZLineView.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZLineView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZLineView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZLineView.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZLineView.h" 10 | 11 | @implementation MZLineView 12 | 13 | - (void)awakeFromNib 14 | { 15 | [super awakeFromNib]; 16 | [self drawOnePixelLine]; 17 | } 18 | 19 | - (void)drawOnePixelLine 20 | { 21 | CGFloat onePixel = 1.0f / [UIScreen mainScreen].scale; 22 | UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, onePixel)]; 23 | lineView.translatesAutoresizingMaskIntoConstraints = NO; 24 | 25 | lineView.backgroundColor = self.backgroundColor; 26 | self.backgroundColor = [UIColor clearColor]; 27 | 28 | [self addSubview:lineView]; 29 | 30 | // Add constraints 31 | NSDictionary *views = NSDictionaryOfVariableBindings(lineView); 32 | NSString *horizontalVFS = @"H:|[lineView]|"; 33 | NSString *verticalVFS = [NSString stringWithFormat:@"V:|[lineView(%f)]", onePixel]; 34 | 35 | NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:horizontalVFS options:0 metrics:nil views:views]; 36 | NSArray *verticalConstriants = [NSLayoutConstraint constraintsWithVisualFormat:verticalVFS options:0 metrics:nil views:views]; 37 | [self addConstraints:[horizontalConstraints arrayByAddingObjectsFromArray:verticalConstriants]]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZPersonCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZPersonCell.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZPersonCell : UITableViewCell 12 | 13 | @property (weak, nonatomic) IBOutlet UIImageView *avatarImageView; 14 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 15 | @property (weak, nonatomic) IBOutlet UILabel *roleLabel; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZPersonCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZPersonCell.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 20/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZPersonCell.h" 10 | 11 | @implementation MZPersonCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZProfileButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfileButton.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MZProfile.h" 11 | 12 | @interface MZProfileButton : UIButton 13 | 14 | - (instancetype)initWithFrame:(CGRect)frame profile:(MZProfile *)profile; 15 | - (instancetype)initWithProfile:(MZProfile *)profile; 16 | 17 | @property (nonatomic) MZProfile *profile; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZProfileButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfileButton.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZProfileButton.h" 10 | #import "UIColor+MZTheme.h" 11 | 12 | @implementation MZProfileButton 13 | 14 | static CGFloat const MZDefaultSize = 28.0f; 15 | 16 | #pragma mark - Initializers 17 | 18 | - (instancetype)initWithFrame:(CGRect)frame profile:(MZProfile *)profile 19 | { 20 | self = [super initWithFrame:frame]; 21 | if (self) { 22 | _profile = profile; 23 | [self setupProfileButton]; 24 | } 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithProfile:(MZProfile *)profile 29 | { 30 | CGRect frame = CGRectMake(0, 0, MZDefaultSize, MZDefaultSize); 31 | return [self initWithFrame:frame profile:profile]; 32 | } 33 | 34 | #pragma mark - Setup 35 | 36 | - (void)setupProfileButton 37 | { 38 | self.adjustsImageWhenHighlighted = NO; 39 | self.layer.cornerRadius = CGRectGetWidth(self.bounds) / 2.0f; 40 | self.layer.masksToBounds = YES; 41 | 42 | [self setPhoto]; 43 | } 44 | 45 | - (void)setPhoto 46 | { 47 | dispatch_async(dispatch_get_main_queue(), ^{ 48 | [self setImage:self.profile.profileImage forState:UIControlStateNormal]; 49 | [self addBorder]; 50 | }); 51 | } 52 | 53 | - (void)addBorder 54 | { 55 | CGFloat onePixel = 1.0f / [UIScreen mainScreen].scale; 56 | self.layer.borderWidth = onePixel; 57 | self.layer.borderColor = [UIColor mz_lightGreyColor].CGColor; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZProfileCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfileCell.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZProfileCell : UITableViewCell 12 | 13 | @property (weak, nonatomic) IBOutlet UILabel *titleLabel; 14 | @property (weak, nonatomic) IBOutlet UILabel *contentLabel; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZProfileCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZProfileCell.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZProfileCell.h" 10 | 11 | @implementation MZProfileCell 12 | 13 | #pragma mark - Initializers 14 | 15 | - (void)tintColorDidChange 16 | { 17 | self.titleLabel.textColor = self.tintColor; 18 | [super tintColorDidChange]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZTopImageButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZTopImageButton.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | IB_DESIGNABLE 12 | @interface MZTopImageButton : UIButton 13 | 14 | @property (nonatomic) IBInspectable CGFloat padding; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/People/Views/MZTopImageButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZTopImageButton.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 27/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZTopImageButton.h" 10 | 11 | @interface MZTopImageButton () 12 | @property (nonatomic) BOOL isInterfaceBuilder; 13 | @end 14 | 15 | @implementation MZTopImageButton 16 | 17 | #pragma mark - Initializers 18 | 19 | - (instancetype)initWithCoder:(NSCoder *)coder 20 | { 21 | self = [super initWithCoder:coder]; 22 | if (self) { 23 | [self sharedInit]; 24 | } 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithFrame:(CGRect)frame 29 | { 30 | self = [super initWithFrame:frame]; 31 | if (self) { 32 | [self sharedInit]; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)sharedInit 38 | { 39 | [self setupInspectableDefaults]; 40 | [self layoutButton]; 41 | } 42 | 43 | - (void)setupInspectableDefaults 44 | { 45 | self.padding = 5.0f; 46 | } 47 | 48 | #pragma mark - Layout 49 | 50 | - (void)layoutButton 51 | { 52 | CGSize imageSize = self.imageView.frame.size; 53 | CGSize titleSize = self.titleLabel.frame.size; 54 | 55 | if (self.isInterfaceBuilder) { 56 | // For some reason self.imageView.frame.size.width does not work in IB 57 | imageSize = [self.imageView intrinsicContentSize]; 58 | titleSize = [self.titleLabel intrinsicContentSize]; 59 | } 60 | 61 | CGFloat totalHeight = imageSize.height + titleSize.height + self.padding; 62 | 63 | self.imageEdgeInsets = UIEdgeInsetsMake(-(totalHeight - imageSize.height), 0, 0, -(titleSize.width)); 64 | self.titleEdgeInsets = UIEdgeInsetsMake(0, -(imageSize.width), -(totalHeight - titleSize.height), 0); 65 | 66 | [self invalidateIntrinsicContentSize]; 67 | } 68 | 69 | #pragma mark - Properties 70 | 71 | - (void)setPadding:(CGFloat)padding 72 | { 73 | _padding = padding; 74 | [self layoutButton]; 75 | } 76 | 77 | - (void)setTitle:(NSString *)title forState:(UIControlState)state 78 | { 79 | [super setTitle:title forState:state]; 80 | [self layoutButton]; 81 | } 82 | 83 | - (void)setImage:(UIImage *)image forState:(UIControlState)state 84 | { 85 | [super setImage:image forState:state]; 86 | [self layoutButton]; 87 | } 88 | 89 | #pragma mark - UIView 90 | 91 | - (CGSize)intrinsicContentSize 92 | { 93 | CGSize intrinsicImageViewSize = [self.imageView intrinsicContentSize]; 94 | CGSize intrinsicTitleLabelSize = [self.titleLabel intrinsicContentSize]; 95 | 96 | CGFloat width = MAX(intrinsicImageViewSize.width, intrinsicTitleLabelSize.width); 97 | CGFloat height = intrinsicImageViewSize.height + self.padding + intrinsicTitleLabelSize.height; 98 | 99 | return CGSizeMake(width, height); 100 | } 101 | 102 | - (void)tintColorDidChange 103 | { 104 | [self setTitleColor:self.tintColor forState:UIControlStateNormal]; 105 | [super tintColorDidChange]; 106 | } 107 | 108 | #pragma mark - Interface Builder 109 | 110 | - (void)prepareForInterfaceBuilder 111 | { 112 | self.isInterfaceBuilder = YES; 113 | 114 | // Need this to make Interface Builder render image in tint color 115 | UIImage *image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 116 | [self setImage:image forState:UIControlStateNormal]; 117 | 118 | [self tintColorDidChange]; 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Theme/MZTheme.h: -------------------------------------------------------------------------------- 1 | // 2 | // MZTheme.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 2/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MZTheme : NSObject 12 | 13 | + (void)setupAppTheme; 14 | 15 | + (UIColor *)globalTintColor; 16 | + (void)setGlobalTintColor:(UIColor *)globalTintColor; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Theme/MZTheme.m: -------------------------------------------------------------------------------- 1 | // 2 | // MZTheme.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 2/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "MZTheme.h" 10 | #import "UIColor+MZTheme.h" 11 | 12 | @implementation MZTheme 13 | 14 | + (void)setupAppTheme 15 | { 16 | [MZTheme setGlobalTintColor:[UIColor mz_defaultTintColor]]; 17 | [MZTheme setTableCellSelectionColor]; 18 | } 19 | 20 | + (UIColor *)globalTintColor 21 | { 22 | return [UIApplication sharedApplication].delegate.window.tintColor; 23 | } 24 | 25 | + (void)setGlobalTintColor:(UIColor *)globalTintColor 26 | { 27 | [UIApplication sharedApplication].delegate.window.tintColor = globalTintColor; 28 | } 29 | 30 | + (void)setTableCellSelectionColor 31 | { 32 | UIView *view = [UIView new]; 33 | view.backgroundColor = [UIColor mz_lightGreyColor]; 34 | [UITableViewCell appearance].selectedBackgroundView = view; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Theme/UIColor+MZTheme.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+MZTheme.h 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 25/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIColor (MZTheme) 12 | 13 | + (UIColor *)mz_colorFromHexCode:(NSString *)hexString; 14 | 15 | + (UIColor *)mz_defaultTintColor; 16 | + (UIColor *)mz_lightGreyColor; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/Theme/UIColor+MZTheme.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+MZTheme.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 25/01/2016. 6 | // Copyright © 2016 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import "UIColor+MZTheme.h" 10 | 11 | @implementation UIColor (MZTheme) 12 | 13 | // http://stackoverflow.com/questions/3805177/how-to-convert-hex-rgb-color-codes-to-uicolor 14 | + (UIColor *)mz_colorFromHexCode:(NSString *)hexString 15 | { 16 | NSString *cleanString = [hexString stringByReplacingOccurrencesOfString:@"#" withString:@""]; 17 | if ([cleanString length] == 3) { 18 | cleanString = [NSString stringWithFormat:@"%@%@%@%@%@%@", 19 | [cleanString substringWithRange:NSMakeRange(0, 1)], [cleanString substringWithRange:NSMakeRange(0, 1)], 20 | [cleanString substringWithRange:NSMakeRange(1, 1)], [cleanString substringWithRange:NSMakeRange(1, 1)], 21 | [cleanString substringWithRange:NSMakeRange(2, 1)], [cleanString substringWithRange:NSMakeRange(2, 1)]]; 22 | } 23 | if ([cleanString length] == 6) { 24 | cleanString = [cleanString stringByAppendingString:@"ff"]; 25 | } 26 | 27 | unsigned int baseValue; 28 | [[NSScanner scannerWithString:cleanString] scanHexInt:&baseValue]; 29 | 30 | float red = ((baseValue >> 24) & 0xFF) / 255.0f; 31 | float green = ((baseValue >> 16) & 0xFF) / 255.0f; 32 | float blue = ((baseValue >> 8) & 0xFF) / 255.0f; 33 | float alpha = ((baseValue >> 0) & 0xFF) / 255.0f; 34 | 35 | return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 36 | } 37 | 38 | #pragma mark - Theme colors 39 | 40 | + (UIColor *)mz_defaultTintColor 41 | { 42 | return [UIColor mz_colorFromHexCode:@"2979FF"]; 43 | } 44 | 45 | + (UIColor *)mz_lightGreyColor 46 | { 47 | return [UIColor mz_colorFromHexCode:@"F2F2F2"]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /MaskZoomTransitionDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MaskZoomTransitionDemo 4 | // 5 | // Created by Steph Sharp on 16/12/2015. 6 | // Copyright © 2015 Stephanie Sharp. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MaskZoomTransition 2 | 3 | A Material Design-style transition, inspired by [this animation](https://dribbble.com/shots/1744157-User-Profile-Interface-Animation) from Dmytro Prudnikov. 4 | 5 | 6 | 7 | 8 | ## Definitions 9 | 10 | ##### smallView 11 | 12 | The small view in the presenting view controller to transition from. 13 | 14 | ##### largeView 15 | 16 | The large view in the presented view controller to transition to. 17 | 18 | ##### viewsToFadeIn 19 | 20 | The views in the presented view controller that fade in at the end of the transition. (Optional) 21 | 22 | 23 | ## Usage 24 | 25 | In the presenting view controller, initialise a property for the transitioning delegate: 26 | 27 | self.transitioningDelegate = [MZMaskZoomTransitioningDelegate new]; 28 | 29 | Assign the `smallView` and `transitioningDelegate` in `prepareForSegue:sender:`: 30 | 31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 32 | { 33 | self.transitioningDelegate.smallView = sender; // The view you are transitioning from. 34 | ... 35 | segue.destinationViewController.transitioningDelegate = self.transitioningDelegate; 36 | segue.destinationViewController.modalPresentationStyle = UIModalPresentationCustom; 37 | } 38 | 39 | Implement the `MZMaskZoomTransitionPresentedViewController` protocol in the presented view controller: 40 | 41 | @synthesize largeView, viewsToFadeIn; 42 | 43 | - (NSArray *)viewsToFadeIn 44 | { 45 | return @[self.label1, self.label2, self.label3]; // Any views you want to fade in at the end of the transition. 46 | } 47 | 48 | - (UIView *)largeView 49 | { 50 | return self.someLargeView; // The view you are transitioning to. 51 | } 52 | 53 | ## Other options 54 | 55 | ##### duration 56 | 57 | Default duration is 0.25 seconds. 58 | 59 | ##### presenting 60 | 61 | Default is YES. It's set to NO when dismissing a view controller (see `MZMaskZoomTransitioningDelegate`). 62 | 63 | ##### dismissToZeroSize 64 | 65 | Default is NO. Set to YES if you want the dismiss transition to shrink the view down to zero. This is useful if the `smallView` in the presenting view controller is no longer visible (e.g. item was deleted). 66 | 67 | 68 | ## Installation 69 | 70 | ### CocoaPods 71 | 72 | To install via CocoaPods, add to your podfile: 73 | 74 | pod 'MaskZoomTransition', '~> 0.1' 75 | 76 | 77 | ## Acknowledgements 78 | 79 | - Transition inspired by Dmytro Prudnikov's [User Profile Interface Animation](https://dribbble.com/shots/1744157-User-Profile-Interface-Animation) (found [here](http://blog.webbb.be/material-design-animation-examples/)) 80 | - Avatars from [Placeit](https://blog.placeit.net/free-avatar-pack/) 81 | - Names generated by [uinames.com](http://uinames.com/) 82 | - Colours chosen from [Google's Material Design spec](https://www.google.com/design/spec/style/color.html#color-color-palette) and [flatuicolorpicker.com](http://www.flatuicolorpicker.com) 83 | 84 | 85 | ## License 86 | 87 | MaskZoomTransition is released under the MIT license. See LICENSE for details. 88 | --------------------------------------------------------------------------------