Commits

Joris Kluivers committed 083131b

Unwinding segue

  • Participants
  • Parent commits 54aba57

Comments (0)

Files changed (8)

File ImageTransition.xcodeproj/project.pbxproj

 		A95F4B9016A198B10024807A /* BeachThumb@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = A95F4B8D16A198B10024807A /* BeachThumb@2x.jpg */; };
 		A95F4B9216A199520024807A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A95F4B9116A199520024807A /* QuartzCore.framework */; };
 		A95F4B9916A1B5520024807A /* JKImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A95F4B9816A1B5520024807A /* JKImageViewController.m */; };
+		A95F4BB416A4A1850024807A /* JKCenterScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = A95F4BB316A4A1850024807A /* JKCenterScrollView.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
 		A95F4B9116A199520024807A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
 		A95F4B9716A1B5520024807A /* JKImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKImageViewController.h; sourceTree = "<group>"; };
 		A95F4B9816A1B5520024807A /* JKImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKImageViewController.m; sourceTree = "<group>"; };
+		A95F4BB216A4A1850024807A /* JKCenterScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKCenterScrollView.h; sourceTree = "<group>"; };
+		A95F4BB316A4A1850024807A /* JKCenterScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKCenterScrollView.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
 				A95F4B8116A197130024807A /* JKViewController.m */,
 				A95F4B9716A1B5520024807A /* JKImageViewController.h */,
 				A95F4B9816A1B5520024807A /* JKImageViewController.m */,
+				A95F4BB216A4A1850024807A /* JKCenterScrollView.h */,
+				A95F4BB316A4A1850024807A /* JKCenterScrollView.m */,
 				A95F4B6C16A197130024807A /* Supporting Files */,
 				A95F4B8816A1978C0024807A /* JKImageTransitionSegue.h */,
 				A95F4B8916A1978C0024807A /* JKImageTransitionSegue.m */,
 				A95F4B8216A197130024807A /* JKViewController.m in Sources */,
 				A95F4B8A16A1978C0024807A /* JKImageTransitionSegue.m in Sources */,
 				A95F4B9916A1B5520024807A /* JKImageViewController.m in Sources */,
+				A95F4BB416A4A1850024807A /* JKCenterScrollView.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 				A95F4B8716A197130024807A /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
 		};
 /* End XCConfigurationList section */
 	};

File ImageTransition/JKCenterScrollView.h

 
 #import <UIKit/UIKit.h>
 
+static NSInteger JKCenterViewTag = 99;
+
 @interface JKCenterScrollView : UIScrollView
 
 @end

File ImageTransition/JKCenterScrollView.m

 
 @implementation JKCenterScrollView
 
-- (id)initWithFrame:(CGRect)frame
+- (void) layoutSubviews
 {
-    self = [super initWithFrame:frame];
-    if (self) {
-        // Initialization code
-    }
-    return self;
+	[super layoutSubviews];
+	
+	UIView *centerView = [self viewWithTag:JKCenterViewTag];
+	if (!centerView) {
+		return;
+	}
+	
+	CGSize boundsSize = self.bounds.size;
+    CGRect frameToCenter = centerView.frame;
+	
+    // center horizontally
+    if (frameToCenter.size.width < boundsSize.width)
+        frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
+    else
+        frameToCenter.origin.x = 0;
+	
+    // center vertically
+    if (frameToCenter.size.height < boundsSize.height)
+        frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
+    else
+        frameToCenter.origin.y = 0;
+	
+    centerView.frame = frameToCenter;
 }
 
-/*
-// Only override drawRect: if you perform custom drawing.
-// An empty implementation adversely affects performance during animation.
-- (void)drawRect:(CGRect)rect
-{
-    // Drawing code
-}
-*/
-
 @end

File ImageTransition/JKImageTransitionSegue.h

 
 @interface JKImageTransitionSegue : UIStoryboardSegue
 
+@property(assign) BOOL unwinding;
+
 @property(assign) CGRect sourceRect;
 @property(assign) CGRect destinationRect;
 

File ImageTransition/JKImageTransitionSegue.m

 {
 	self = [super initWithIdentifier:identifier source:source destination:destination];
 	if (self) {
+		_unwinding = NO;
 		_destinationRect = CGRectZero;
 	}
 	return self;
 			roundf((CGRectGetWidth(screenBounds) - CGRectGetWidth(dest)) / 2.0f),
 			roundf((CGRectGetHeight(screenBounds) - CGRectGetHeight(dest)) / 2.0f)
 		);
+	} else {
+		UIView *sourceView = ((UIViewController *)self.sourceViewController).view;
+		dest = [sourceView convertRect:dest toView:sourceView.window];
+		
+		// TODO: tmp fix for status bar
+		dest.origin.y += 20.0f;
 	}
 	
 	[UIView animateWithDuration:0.4f delay:.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
 		
 		imageView.frame = dest;
 		
-		((UIViewController *)self.destinationViewController).modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
-		[self.sourceViewController presentViewController:self.destinationViewController animated:YES completion:nil];
+		if (self.unwinding) {
+			[self.destinationViewController dismissViewControllerAnimated:YES completion:nil];
+		} else {
+			((UIViewController *)self.destinationViewController).modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
+			[self.sourceViewController presentViewController:self.destinationViewController animated:YES completion:nil];
+		}
 	} completion:^(BOOL completed) {
 		imageView.hidden = YES;
 		[imageView removeFromSuperview];
 	}];
-	
-	
 }
 
 @end

File ImageTransition/JKImageViewController.m

 #import <QuartzCore/QuartzCore.h>
 
 #import "JKImageViewController.h"
+#import "JKCenterScrollView.h"
 
 @interface JKImageViewController ()
 
 {
     [super viewDidLoad];
 	
-	self.scrollView.contentSize = [UIScreen mainScreen].bounds.size;
+	self.imageView.tag = JKCenterViewTag;
 }
 
 - (void) viewWillAppear:(BOOL)animated
 {
+	/*if (animated) {
+		[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
+	} else {
+		[UIApplication sharedApplication].statusBarHidden = YES;
+	}*/
+	
 	self.imageView.hidden = YES;
 	self.imageView.image = self.image;
 }
 - (void) viewDidAppear:(BOOL)animated
 {
 	self.imageView.hidden = NO;
+	
+	CGFloat factor = fminf(CGRectGetWidth(self.scrollView.frame) / self.image.size.width, CGRectGetHeight(self.scrollView.frame) / self.image.size.height);
+	
+	CGRect position = CGRectZero;
+	position.size = CGSizeMake(self.image.size.width*factor, self.image.size.height * factor);
+	self.imageView.frame = position;
+	self.imageView.center = CGPointMake(CGRectGetMidX(self.scrollView.frame), CGRectGetMidY(self.scrollView.frame));
+	
+	self.scrollView.contentSize = position.size;	
+}
+
+- (void) viewWillDisappear:(BOOL)animated
+{
+	//[UIApplication sharedApplication].statusBarHidden = NO;
+}
+
+- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+	NSLog(@"%s", __func__);
 }
 
 #pragma mark - Scroll & Zoom
 	return self.imageView;
 }
 
+- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
+	if (scrollView.zoomScale > 1.0) {
+		return;
+	}
+	
+	if (fabsf(scrollView.contentOffset.y) < 50.0f) {
+		return;
+	}
+	
+	NSLog(@"Dismiss!");
+	
+	[self performSegueWithIdentifier:@"ExitSegue" sender:self];
+}
+
 @end

File ImageTransition/JKViewController.m

 	self.imageButton.layer.shadowRadius = 1.0f;
 }
 
+- (void) viewDidAppear:(BOOL)animated
+{
+	self.imageButton.hidden = NO;
+}
+
 - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
 {
 	if (![segue isKindOfClass:[JKImageTransitionSegue class]]) {
 
 - (IBAction) unwindFromSegue:(UIStoryboardSegue *)segue
 {
-	self.imageButton.hidden = NO;
+	
 }
 
 - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
 {
-	// TODO: return a custom segue to unwind using a custom transition
-	return [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
+	JKImageTransitionSegue *imageTransition = [[JKImageTransitionSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController];
+	imageTransition.unwinding = YES;
+	imageTransition.transitionImage = self.imageButton.imageView.image;
+	
+	CGRect sourceRect = ((JKImageViewController *)fromViewController).imageView.frame;
+	sourceRect.origin.y -= ((JKImageViewController *)fromViewController).scrollView.contentOffset.y;
+	sourceRect.origin.x -= ((JKImageViewController *)fromViewController).scrollView.contentOffset.x;
+	imageTransition.sourceRect = sourceRect;
+	
+	imageTransition.destinationRect = self.imageButton.frame;
+	
+	((JKImageViewController *)fromViewController).imageView.hidden = YES;
+	
+	return imageTransition;
 }
 
 @end

File ImageTransition/en.lproj/MainStoryboard.storyboard

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="2844" systemVersion="12C60" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="2">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="2844" systemVersion="12C60" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="2">
     <dependencies>
         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1930"/>
     </dependencies>
                         <rect key="frame" x="0.0" y="20" width="320" height="548"/>
                         <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                         <subviews>
-                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bsC-CX-Mba">
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="bsC-CX-Mba">
+                                <rect key="frame" x="10" y="74" width="300" height="188"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
                                 <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
                                 <state key="normal" image="BeachThumb.jpg">
                                     <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
                             </button>
                         </subviews>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
-                        <constraints>
-                            <constraint firstItem="bsC-CX-Mba" firstAttribute="top" secondItem="3" secondAttribute="top" constant="74" id="4Vn-32-BZv"/>
-                            <constraint firstItem="bsC-CX-Mba" firstAttribute="centerX" secondItem="3" secondAttribute="centerX" type="default" id="KMc-kJ-zXP"/>
-                        </constraints>
                     </view>
                     <connections>
                         <outlet property="imageButton" destination="bsC-CX-Mba" id="DZs-Yo-DAV"/>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="4" sceneMemberID="firstResponder"/>
             </objects>
-            <point key="canvasLocation" x="-215" y="-33"/>
+            <point key="canvasLocation" x="-1127" y="-21"/>
         </scene>
         <!--Image View Controller-->
         <scene sceneID="a6G-mg-rld">
                         <rect key="frame" x="0.0" y="20" width="320" height="548"/>
                         <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                         <subviews>
-                            <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" maximumZoomScale="2" translatesAutoresizingMaskIntoConstraints="NO" id="Rwk-xo-GEk">
+                            <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" maximumZoomScale="4" id="Rwk-xo-GEk" customClass="JKCenterScrollView">
+                                <rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                 <subviews>
-                                    <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="NTE-Pk-wLb"/>
+                                    <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" id="NTE-Pk-wLb">
+                                        <rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
+                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                    </imageView>
                                 </subviews>
-                                <constraints>
-                                    <constraint firstItem="NTE-Pk-wLb" firstAttribute="top" secondItem="Rwk-xo-GEk" secondAttribute="top" type="default" id="8MH-Uy-49P"/>
-                                    <constraint firstItem="NTE-Pk-wLb" firstAttribute="bottom" secondItem="Rwk-xo-GEk" secondAttribute="bottom" type="default" id="l62-ag-72v"/>
-                                    <constraint firstAttribute="centerX" secondItem="NTE-Pk-wLb" secondAttribute="centerX" type="user" id="mlp-H1-xjx"/>
-                                    <constraint firstItem="NTE-Pk-wLb" firstAttribute="trailing" secondItem="Rwk-xo-GEk" secondAttribute="trailing" type="default" id="pxX-Y3-IA1"/>
-                                    <constraint firstItem="NTE-Pk-wLb" firstAttribute="leading" secondItem="Rwk-xo-GEk" secondAttribute="leading" type="default" id="wQU-zm-3yl"/>
-                                    <constraint firstItem="NTE-Pk-wLb" firstAttribute="centerY" secondItem="Rwk-xo-GEk" secondAttribute="centerY" type="default" id="xoQ-DD-jWY"/>
-                                </constraints>
                                 <connections>
                                     <outlet property="delegate" destination="qlX-TB-qXw" id="h09-YD-XSW"/>
                                 </connections>
                             </scrollView>
-                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uHe-BA-wNi">
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="uHe-BA-wNi">
+                                <rect key="frame" x="238" y="20" width="62" height="44"/>
+                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
                                 <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
                                 <state key="normal" title="Done">
                                     <color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
                                     <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                                 </state>
                                 <connections>
-                                    <segue destination="zyv-8Z-hCj" kind="unwind" unwindAction="unwindFromSegue:" id="Dx9-Gs-AHx"/>
+                                    <segue destination="zyv-8Z-hCj" kind="unwind" identifier="ExitSegue" unwindAction="unwindFromSegue:" id="Dx9-Gs-AHx"/>
                                 </connections>
                             </button>
                         </subviews>
                         <color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
-                        <constraints>
-                            <constraint firstItem="Rwk-xo-GEk" firstAttribute="bottom" secondItem="Amj-XQ-9JQ" secondAttribute="bottom" type="default" id="KGR-1C-6WP"/>
-                            <constraint firstItem="uHe-BA-wNi" firstAttribute="top" secondItem="Amj-XQ-9JQ" secondAttribute="top" constant="40" id="Qii-SD-1WI"/>
-                            <constraint firstItem="Rwk-xo-GEk" firstAttribute="top" secondItem="Amj-XQ-9JQ" secondAttribute="top" type="default" id="RQP-ac-BZ1"/>
-                            <constraint firstItem="Rwk-xo-GEk" firstAttribute="leading" secondItem="Amj-XQ-9JQ" secondAttribute="leading" type="default" id="hxH-FX-hnk"/>
-                            <constraint firstItem="Rwk-xo-GEk" firstAttribute="trailing" secondItem="Amj-XQ-9JQ" secondAttribute="trailing" type="default" id="tJq-p9-Clh"/>
-                            <constraint firstAttribute="trailing" secondItem="uHe-BA-wNi" secondAttribute="trailing" constant="20" symbolic="YES" type="default" id="xZL-t7-VYO"/>
-                        </constraints>
                     </view>
                     <simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="blackOpaque"/>
                     <nil key="simulatedTopBarMetrics"/>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="trF-LE-Gsy" userLabel="First Responder" sceneMemberID="firstResponder"/>
                 <exit id="zyv-8Z-hCj" userLabel="Exit" sceneMemberID="exit"/>
             </objects>
-            <point key="canvasLocation" x="279" y="-33"/>
+            <point key="canvasLocation" x="-633" y="-21"/>
         </scene>
     </scenes>
     <resources>
         <image name="BeachThumb.jpg" width="300" height="188"/>
     </resources>
     <classes>
+        <class className="JKCenterScrollView" superclassName="UIScrollView">
+            <source key="sourceIdentifier" type="project" relativePath="./Classes/JKCenterScrollView.h"/>
+        </class>
         <class className="JKImageViewController" superclassName="UIViewController">
             <source key="sourceIdentifier" type="project" relativePath="./Classes/JKImageViewController.h"/>
             <relationships>
                 <relationship kind="outlet" name="imageButton" candidateClass="UIButton"/>
             </relationships>
         </class>
-        <class className="NSLayoutConstraint" superclassName="NSObject">
-            <source key="sourceIdentifier" type="project" relativePath="./Classes/NSLayoutConstraint.h"/>
-        </class>
         <class className="UIStoryboardSegue" superclassName="NSObject">
             <source key="sourceIdentifier" type="project" relativePath="./Classes/UIStoryboardSegue.h"/>
         </class>