Skip to content

Instantly share code, notes, and snippets.

@roothybrid7
Created February 2, 2014 10:42
Show Gist options
  • Save roothybrid7/8766306 to your computer and use it in GitHub Desktop.
Save roothybrid7/8766306 to your computer and use it in GitHub Desktop.
Segueを使ってUINavigationControllerの画面遷移アニメーションを変更する ref: http://qiita.com/roothybrid7/items/532b63175da30fa9a2b1
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "MyNavigationController.h"
#import "NavigateFlipSegue.h"
@interface MasterViewController () <MyNavigationControllerDelegate> // 委譲用プロトコルの適用
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
@end
@implementation MasterViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
[[segue destinationViewController] setDetailItem:object];
}
}
// unwind segueの定義
- (IBAction)exitToMasterView:(UIStoryboardSegue *)segue
{
// XXX: No-op. unwind segue.
}
#pragma mark - MyNavigationControllerDelegate
// 委譲用プロトコルメソッドの実装
- (UIStoryboardSegue *)segueInNavigationControllerForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
{
if ([identifier isEqualToString:@"existFromDetail"]) { // custom segueの生成
NavigateFlipSegue *segue = [[NavigateFlipSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController];
segue.unwind = YES; // unwind segueなのでセット
return segue;
}
return nil;
}
#import <UIKit/UIKit.h>
// ChildViewControllerで実装
@protocol MyNavigationControllerDelegate <NSObject>
/*!
@method segueInNavigationControllerForUnwindingToViewController:fromViewController:identifier:
@abstract NavigationControllerによる遷移でunwindする場合、custom segueを使いたい場合に実装する
@discussion 戻る側のViewControllerでunwind segueの実装してNavigationControllerでは何もしない(委譲)
@return Custom Segueを生成して返すように実装
*/
- (UIStoryboardSegue *)segueInNavigationControllerForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier;
@end
@interface MyNavigationController : UINavigationController
@end
#import "MyNavigationController.h"
@interface MyNavigationController ()
@end
@implementation MyNavigationController
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
{
// MARK: 実際の戻り先ChildViewControllerに処理を任せる
if ([toViewController conformsToProtocol:@protocol(MyNavigationControllerDelegate)]) {
id <MyNavigationControllerDelegate> destinationViewController = (id <MyNavigationControllerDelegate>)toViewController;
UIStoryboardSegue *segue = [destinationViewController segueInNavigationControllerForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
if (segue) {
return segue;
}
}
return [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
}
@end
#import <UIKit/UIKit.h>
@interface NavigateFlipSegue : UIStoryboardSegue
@property (nonatomic) BOOL unwind; // unwind segueのインスタンスを作成時に設定するflag
@end
#import "NavigateFlipSegue.h"
@implementation NavigateFlipSegue
- (void)perform
{
UIViewController *sourceViewController = self.sourceViewController;
UIViewController *destinationViewController = self.destinationViewController;
UINavigationController *navigationController = sourceViewController.navigationController;
if (self.unwind) { // Unwind segueの場合は、右からflipするアニメーション
[UIView transitionWithView:navigationController.view duration:0.3f options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
[navigationController popToRootViewControllerAnimated:NO];
} completion:nil];
} else { // segueの場合は、左からflipするアニメーション
[UIView transitionWithView:navigationController.view duration:0.3f options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
[navigationController pushViewController:destinationViewController animated:NO];
} completion:nil];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment