Skip to content

Instantly share code, notes, and snippets.

@junpluse
Last active April 26, 2024 08:15
Show Gist options
  • Save junpluse/4125217 to your computer and use it in GitHub Desktop.
Save junpluse/4125217 to your computer and use it in GitHub Desktop.
Simple implementation for swipe-to-back/forward UINavigationController
#import <UIKit/UIKit.h>
@interface SwipeNavigationController : UINavigationController <UIGestureRecognizerDelegate>
@property (nonatomic, readonly) NSArray *poppedViewControllers;
- (void)clearPoppedViewControllers;
@property (nonatomic, readonly) UISwipeGestureRecognizer *leftSwipeGestureRecognizer;
@property (nonatomic, readonly) UISwipeGestureRecognizer *rightSwipeGestureRecognizer;
- (void)handleLeftSwipeGesture:(UISwipeGestureRecognizer *)gestureRecognizer;
- (void)handleRightSwipeGesture:(UISwipeGestureRecognizer *)gestureRecognizer;
@end
#import "SwipeNavigationController.h"
@implementation SwipeNavigationController {
NSMutableArray *_poppedViewControllers;
}
#pragma mark UIViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_swipeNavigationEnabled = YES;
_poppedViewControllers = [NSMutableArray new];
}
return self;
}
- (void)awakeFromNib
{
_swipeNavigationEnabled = YES;
_poppedViewControllers = [NSMutableArray new];
}
- (void)viewDidLoad
{
[super viewDidLoad];
{
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipeGesture:)];
recognizer.direction = UISwipeGestureRecognizerDirectionLeft;
recognizer.delegate = self;
[self.view addGestureRecognizer:recognizer];
_leftSwipeGestureRecognizer = recognizer;
}{
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipeGesture:)];
recognizer.direction = UISwipeGestureRecognizerDirectionRight;
recognizer.delegate = self;
[self.view addGestureRecognizer:recognizer];
_rightSwipeGestureRecognizer = recognizer;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[self clearPoppedViewControllers];
}
#pragma mark UINavigationController
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([self.poppedViewControllers count] > 0) {
if (viewController == [self.poppedViewControllers lastObject]) {
[_poppedViewControllers removeLastObject];
} else {
[_poppedViewControllers removeAllObjects];
}
}
[super pushViewController:viewController animated:animated];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
UIViewController *controller = [super popViewControllerAnimated:animated];
[_poppedViewControllers addObject:controller];
return controller;
}
#pragma mark UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if (!self.swipeNavigationEnabled) {
return NO;
} else if (gestureRecognizer == self.leftSwipeGestureRecognizer) {
return ([self.poppedViewControllers count] > 0);
} else if (gestureRecognizer == self.rightSwipeGestureRecognizer) {
return ([self.viewControllers count] > 1);
}
return YES;
}
#pragma mark SwipeNavigationController
- (void)clearPoppedViewControllers
{
[_poppedViewControllers removeAllObjects];
}
- (void)handleLeftSwipeGesture:(UISwipeGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateRecognized
&& self.swipeNavigationEnabled
&& self.visibleViewController
&& ![self.visibleViewController isBeingPresented]
&& ![self.visibleViewController isBeingDismissed]) {
[self pushViewController:[self.poppedViewControllers lastObject] animated:YES];
}
}
- (void)handleRightSwipeGesture:(UISwipeGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateRecognized
&& self.swipeNavigationEnabled
&& self.visibleViewController
&& ![self.visibleViewController isBeingPresented]
&& ![self.visibleViewController isBeingDismissed]) {
[self popViewControllerAnimated:YES];
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment