Last active
March 24, 2016 11:24
-
-
Save andrey-str/8a8567118c3d286dbe8a to your computer and use it in GitHub Desktop.
UIView Container pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Andrey Streltsov on 09/03/16. | |
// | |
@import UIKit; | |
enum eViewControllerIndentifiers { | |
eIdentifier1, // the one with rendered whole course map | |
eIdentifier2, // the one with MapKit map | |
eIdentifier3 // the one with rendered hole map | |
}; | |
@interface ViewsContainerController : UIViewController | |
- (void) switchTo:(enum eViewControllerIndentifiers)viewControllerIdentifier; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Created by Andrey Streltsov on 09/03/16. | |
// Note: need to edit before use. | |
#import "ViewsContainerController.h" | |
#import "ViewController1.h" | |
#import "ViewController2.h" | |
#import "ViewController3.h" | |
#import "Additions.h" | |
#define kSegueIdentifier1 @"segue1" | |
#define kSegueIdentifier2 @"segue2" | |
#define kSegueIdentifier3 @"segue3" | |
@interface ViewsContainerController () | |
@property (strong, nonatomic) NSString *currentSegueIdentifier; | |
@property (strong, nonatomic) NSObject<UIViewController> *viewController1; | |
@property (strong, nonatomic) NSObject<UIViewController> *viewController2; | |
@property (strong, nonatomic) NSObject<UIViewController> *viewController3; | |
@property (assign, nonatomic) BOOL transitionInProgress; | |
@property(nonatomic, strong) UIViewController *currentViewController; | |
@property (nonatomic, weak) IBOutlet UIActivityIndicatorView *activityIndicatorView; | |
@end | |
@implementation ViewsContainerController{ | |
} | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
self.transitionInProgress = NO; | |
[self.activityIndicatorView startAnimating]; | |
} | |
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender | |
{ | |
DLog(@""); | |
// Instead of creating new VCs on each seque we want to hang on to existing | |
// instances if we have it. Remove the second condition of the following | |
// two if statements to get new VC instances instead. | |
if ([segue.identifier isEqualToString:kSegueIdentifier2]) { | |
self.viewController2 = segue.destinationViewController; | |
} | |
if ([segue.identifier isEqualToString:kSegueIdentifier3]) { | |
self.viewController3 = segue.destinationViewController; | |
} | |
if ([segue.identifier isEqualToString:kSegueIdentifier1]) { | |
self.viewController1 = segue.destinationViewController; | |
} | |
// If we're going to the segment view controller view controller. | |
if ([segue.identifier isEqualToString:kSegueIdentifier2]) { | |
// If this is not the first time we're loading this. | |
if (self.childViewControllers.count > 0) { | |
[self swapFromViewController:self.childViewControllers[0] | |
toViewController:self.viewController2]; | |
} | |
else { | |
// If this is the very first time we're loading this we need to do | |
// an initial load and not a swap. | |
[self addChildViewController:segue.destinationViewController]; | |
UIView* destView = segue.destinationViewController.view; | |
destView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; | |
destView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); | |
[self.view addSubview:destView]; | |
[segue.destinationViewController didMoveToParentViewController:self]; | |
self.currentViewController = segue.destinationViewController; | |
} | |
} | |
else if ([segue.identifier isEqualToString:kSegueIdentifier1]) { | |
[self swapFromViewController:self.childViewControllers[0] toViewController:self.viewController1]; | |
} | |
else if([segue.identifier isEqualToString:kSegueIdentifier3]) { | |
[self swapFromViewController:self.childViewControllers[0] toViewController:self.viewController3]; | |
} | |
} | |
- (void)swapFromViewController:(UIViewController *)fromViewController | |
toViewController:(UIViewController *)toViewController | |
{ | |
DLog(@""); | |
toViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); | |
[fromViewController willMoveToParentViewController:nil]; | |
[self addChildViewController:toViewController]; | |
[self transitionFromViewController:fromViewController toViewController:toViewController | |
duration:0.1 options:UIViewAnimationOptionTransitionCrossDissolve | |
animations:nil completion:^(BOOL finished) { | |
[fromViewController removeFromParentViewController]; | |
[toViewController didMoveToParentViewController:self]; | |
self.transitionInProgress = NO; | |
self.currentViewController = toViewController; | |
}]; | |
} | |
- (void)switchTo:(enum eMapsViewControllerIndentifiers)viewControllerIdentifier { | |
if (self.transitionInProgress) { | |
return; | |
} | |
if([[[self class] sequeIdentifierWithMapsViewControllerIdentifier: viewControllerIdentifier] isEqualToString: self.currentSegueIdentifier]) | |
return; | |
if(![self.childViewControllers count]){ | |
self.currentSegueIdentifier = kSegueIdentifier2; | |
[self performSegueWithIdentifier:self.currentSegueIdentifier sender:nil]; | |
return; | |
} | |
self.transitionInProgress = YES; | |
UIViewController * newViewController; | |
switch(viewControllerIdentifier){ | |
case eSatelliteIdentifier: | |
self.currentSegueIdentifier = kSegueIdentifier1; | |
newViewController = self.viewController1; | |
break; | |
case eMapViewIdentifier: | |
self.currentSegueIdentifier = kSegueIdentifier3; | |
newViewController = self.viewController3; | |
break; | |
case eSegmentViewIdentifier: | |
self.currentSegueIdentifier = kSegueIdentifier2; | |
newViewController = self.viewController2; | |
break; | |
} | |
if(newViewController) { | |
[self swapFromViewController:self.currentViewController toViewController:newViewController]; | |
return; | |
} | |
[self performSegueWithIdentifier:self.currentSegueIdentifier sender:nil]; | |
} | |
+ (NSString*) sequeIdentifierWithMapsViewControllerIdentifier:(enum eViewControllerIndentifiers)viewControllerIdentifier{ | |
NSString* result = nil; | |
switch(viewControllerIdentifier){ | |
case eIdentifier1: | |
result = kSegueIdentifier1; | |
break; | |
case eIdentifier3: | |
result = kSegueIdentifier3; | |
break; | |
case eIdentifier2: | |
result = kSegueIdentifier2; | |
break; | |
} | |
return result; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment