98 lines
3.4 KiB
Swift
98 lines
3.4 KiB
Swift
//
|
|
// BrowserNavigationController.swift
|
|
// Gemini-iOS
|
|
//
|
|
// Created by Shadowfacts on 12/16/20.
|
|
//
|
|
|
|
import UIKit
|
|
import BrowserCore
|
|
import Combine
|
|
|
|
class BrowserNavigationController: UINavigationController {
|
|
|
|
let navigator: NavigationManager
|
|
|
|
var poppedViewControllers = [UIViewController]()
|
|
var skipResetPoppedOnNextPush = false
|
|
|
|
private var interactivePushTransition: InteractivePushTransition!
|
|
|
|
private var cancellables = [AnyCancellable]()
|
|
|
|
init(navigator: NavigationManager) {
|
|
self.navigator = navigator
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
|
|
navigator.$currentURL
|
|
.sink { [weak self] (newURL) in
|
|
self?.pushViewController(BrowserWebViewController(navigator: navigator, url: newURL), animated: true)
|
|
}
|
|
.store(in: &cancellables)
|
|
}
|
|
|
|
required init?(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
interactivePushTransition = InteractivePushTransition(navigationController: self)
|
|
}
|
|
|
|
override func popViewController(animated: Bool) -> UIViewController? {
|
|
if let popped = super.popViewController(animated: animated) {
|
|
poppedViewControllers.insert(popped, at: 0)
|
|
return popped
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
override func popToRootViewController(animated: Bool) -> [UIViewController]? {
|
|
if let popped = super.popToRootViewController(animated: animated) {
|
|
poppedViewControllers = popped
|
|
return popped
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
override func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? {
|
|
if let popped = super.popToViewController(viewController, animated: animated) {
|
|
poppedViewControllers.insert(contentsOf: popped, at: 0)
|
|
return popped
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
|
|
if skipResetPoppedOnNextPush {
|
|
skipResetPoppedOnNextPush = false
|
|
} else {
|
|
self.poppedViewControllers = []
|
|
}
|
|
super.pushViewController(viewController, animated: animated)
|
|
}
|
|
|
|
func onWillShow() {
|
|
self.transitionCoordinator?.notifyWhenInteractionChanges({ (context) in
|
|
if context.isCancelled {
|
|
if self.interactivePushTransition.interactive {
|
|
// when an interactive push gesture is cancelled, make sure to adding the VC that was being pushed back onto the popped stack so it doesn't disappear
|
|
self.poppedViewControllers.insert(self.interactivePushTransition.pushingViewController!, at: 0)
|
|
} else {
|
|
// when an interactive pop gesture is cancelled (i.e. the user lifts their finger before it triggers),
|
|
// the popViewController(animated:) method has already been called so the VC has already been added to the popped stack
|
|
// so we make sure to remove it, otherwise there could be duplicate VCs on the navigation stasck
|
|
self.poppedViewControllers.remove(at: 0)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|