mirror of
				https://github.com/SoPat712/YTLitePlus.git
				synced 2025-10-31 04:44:14 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			197 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Objective-C
		
	
	
	
	
	
| //
 | |
| //  FLEXNavigationController.m
 | |
| //  FLEX
 | |
| //
 | |
| //  Created by Tanner on 1/30/20.
 | |
| //  Copyright © 2020 FLEX Team. All rights reserved.
 | |
| //
 | |
| 
 | |
| #import "FLEXNavigationController.h"
 | |
| #import "FLEXExplorerViewController.h"
 | |
| #import "FLEXTabList.h"
 | |
| 
 | |
| @interface UINavigationController (Private) <UIGestureRecognizerDelegate>
 | |
| - (void)_gestureRecognizedInteractiveHide:(UIGestureRecognizer *)sender;
 | |
| @end
 | |
| @interface UIPanGestureRecognizer (Private)
 | |
| - (void)_setDelegate:(id)delegate;
 | |
| @end
 | |
| 
 | |
| @interface FLEXNavigationController ()
 | |
| @property (nonatomic, readonly) BOOL toolbarWasHidden;
 | |
| @property (nonatomic) BOOL waitingToAddTab;
 | |
| @property (nonatomic, readonly) BOOL canShowToolbar;
 | |
| @property (nonatomic) BOOL didSetupPendingDismissButtons;
 | |
| @property (nonatomic) UISwipeGestureRecognizer *navigationBarSwipeGesture;
 | |
| @end
 | |
| 
 | |
| @implementation FLEXNavigationController
 | |
| 
 | |
| + (instancetype)withRootViewController:(UIViewController *)rootVC {
 | |
|     return [[self alloc] initWithRootViewController:rootVC];
 | |
| }
 | |
| 
 | |
| - (void)viewDidLoad {
 | |
|     [super viewDidLoad];
 | |
|     
 | |
|     self.waitingToAddTab = YES;
 | |
|     
 | |
|     // Add gesture to reveal toolbar if hidden
 | |
|     UITapGestureRecognizer *navbarTapGesture = [[UITapGestureRecognizer alloc]
 | |
|         initWithTarget:self action:@selector(handleNavigationBarTap:)
 | |
|     ];
 | |
|     
 | |
|     // Don't cancel touches to work around bug on versions of iOS prior to 13
 | |
|     navbarTapGesture.cancelsTouchesInView = NO;
 | |
|     [self.navigationBar addGestureRecognizer:navbarTapGesture];
 | |
|     
 | |
|     // Add gesture to dismiss if not presented with a sheet style
 | |
|     if (@available(iOS 13, *)) {
 | |
|         switch (self.modalPresentationStyle) {
 | |
|             case UIModalPresentationAutomatic:
 | |
|             case UIModalPresentationPageSheet:
 | |
|             case UIModalPresentationFormSheet:
 | |
|                 break;
 | |
|                 
 | |
|             default:
 | |
|                 [self addNavigationBarSwipeGesture];
 | |
|                 break;
 | |
|         }
 | |
|     } else {
 | |
|         [self addNavigationBarSwipeGesture];
 | |
|     }
 | |
| }
 | |
| 
 | |
| - (void)viewWillAppear:(BOOL)animated {
 | |
|     [super viewWillAppear:animated];
 | |
|     
 | |
|     if (self.beingPresented && !self.didSetupPendingDismissButtons) {
 | |
|         for (UIViewController *vc in self.viewControllers) {
 | |
|             [self addNavigationBarItemsToViewController:vc.navigationItem];
 | |
|         }
 | |
|         
 | |
|         self.didSetupPendingDismissButtons = YES;
 | |
|     }
 | |
| }
 | |
| 
 | |
| - (void)viewDidAppear:(BOOL)animated {
 | |
|     [super viewDidAppear:animated];
 | |
|     
 | |
|     if (self.waitingToAddTab) {
 | |
|         // Only add new tab if we're presented properly
 | |
|         if ([self.presentingViewController isKindOfClass:[FLEXExplorerViewController class]]) {
 | |
|             // New navigation controllers always add themselves as new tabs,
 | |
|             // tabs are closed by FLEXExplorerViewController
 | |
|             [FLEXTabList.sharedList addTab:self];
 | |
|             self.waitingToAddTab = NO;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
 | |
|     [super pushViewController:viewController animated:animated];
 | |
|     [self addNavigationBarItemsToViewController:viewController.navigationItem];
 | |
| }
 | |
| 
 | |
| - (void)dismissAnimated {
 | |
|     // Tabs are only closed if the done button is pressed; this
 | |
|     // allows you to leave a tab open by dragging down to dismiss
 | |
|     if ([self.presentingViewController isKindOfClass:[FLEXExplorerViewController class]]) {
 | |
|         [FLEXTabList.sharedList closeTab:self];        
 | |
|     }
 | |
|     
 | |
|     [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
 | |
| }
 | |
| 
 | |
| - (BOOL)canShowToolbar {
 | |
|     return self.topViewController.toolbarItems.count > 0;
 | |
| }
 | |
| 
 | |
| - (void)addNavigationBarItemsToViewController:(UINavigationItem *)navigationItem {
 | |
|     if (!self.presentingViewController) {
 | |
|         return;
 | |
|     }
 | |
|     
 | |
|     // Check if a done item already exists
 | |
|     for (UIBarButtonItem *item in navigationItem.rightBarButtonItems) {
 | |
|         if (item.style == UIBarButtonItemStyleDone) {
 | |
|             return;
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     // Give root view controllers a Done button if it does not already have one
 | |
|     UIBarButtonItem *done = [[UIBarButtonItem alloc]
 | |
|         initWithBarButtonSystemItem:UIBarButtonSystemItemDone
 | |
|         target:self
 | |
|         action:@selector(dismissAnimated)
 | |
|     ];
 | |
|     
 | |
|     // Prepend the button if other buttons exist already
 | |
|     NSArray *existingItems = navigationItem.rightBarButtonItems;
 | |
|     if (existingItems.count) {
 | |
|         navigationItem.rightBarButtonItems = [@[done] arrayByAddingObjectsFromArray:existingItems];
 | |
|     } else {
 | |
|         navigationItem.rightBarButtonItem = done;
 | |
|     }
 | |
|     
 | |
|     // Keeps us from calling this method again on
 | |
|     // the same view controllers in -viewWillAppear:
 | |
|     self.didSetupPendingDismissButtons = YES;
 | |
| }
 | |
| 
 | |
| - (void)addNavigationBarSwipeGesture {
 | |
|     UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc]
 | |
|         initWithTarget:self action:@selector(handleNavigationBarSwipe:)
 | |
|     ];
 | |
|     swipe.direction = UISwipeGestureRecognizerDirectionDown;
 | |
|     swipe.delegate = self;
 | |
|     self.navigationBarSwipeGesture = swipe;
 | |
|     [self.navigationBar addGestureRecognizer:swipe];
 | |
| }
 | |
| 
 | |
| - (void)handleNavigationBarSwipe:(UISwipeGestureRecognizer *)sender {
 | |
|     if (sender.state == UIGestureRecognizerStateRecognized) {
 | |
|         [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
 | |
|     }
 | |
| }
 | |
|      
 | |
| - (void)handleNavigationBarTap:(UIGestureRecognizer *)sender {
 | |
|     // Don't reveal the toolbar if we were just tapping a button
 | |
|     CGPoint location = [sender locationInView:self.navigationBar];
 | |
|     UIView *hitView = [self.navigationBar hitTest:location withEvent:nil];
 | |
|     if ([hitView isKindOfClass:[UIControl class]]) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (sender.state == UIGestureRecognizerStateRecognized) {
 | |
|         if (self.toolbarHidden && self.canShowToolbar) {
 | |
|             [self setToolbarHidden:NO animated:YES];
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| - (BOOL)gestureRecognizer:(UIGestureRecognizer *)g1 shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)g2 {
 | |
|     if (g1 == self.navigationBarSwipeGesture && g2 == self.barHideOnSwipeGestureRecognizer) {
 | |
|         return YES;
 | |
|     }
 | |
|     
 | |
|     return NO;
 | |
| }
 | |
| 
 | |
| - (void)_gestureRecognizedInteractiveHide:(UIPanGestureRecognizer *)sender {
 | |
|     if (sender.state == UIGestureRecognizerStateRecognized) {
 | |
|         BOOL show = self.canShowToolbar;
 | |
|         CGFloat yTranslation = [sender translationInView:self.view].y;
 | |
|         CGFloat yVelocity = [sender velocityInView:self.view].y;
 | |
|         if (yVelocity > 2000) {
 | |
|             [self setToolbarHidden:YES animated:YES];
 | |
|         } else if (show && yTranslation > 20 && yVelocity > 250) {
 | |
|             [self setToolbarHidden:NO animated:YES];
 | |
|         } else if (yTranslation < -20) {
 | |
|             [self setToolbarHidden:YES animated:YES];
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| @end
 | 
