Skip to content

Instantly share code, notes, and snippets.

@andrey-str
Last active March 24, 2016 11:24
Show Gist options
  • Save andrey-str/8a8567118c3d286dbe8a to your computer and use it in GitHub Desktop.
Save andrey-str/8a8567118c3d286dbe8a to your computer and use it in GitHub Desktop.
UIView Container pattern
//
// 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
//
// 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