summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2020-09-17 17:51:42 +0200
committerAndrej Mihajlov <and@mullvad.net>2021-02-24 11:19:07 +0100
commitcbf5a1ce71893522af5e79ed4e655ae7e487dd30 (patch)
treee0e11ce84e62b7883aa3761d80c91d15de91582c
parentd3816ce772bf1a050f8a33d73e25ed3efec7c885 (diff)
downloadmullvadvpn-cbf5a1ce71893522af5e79ed4e655ae7e487dd30.tar.xz
mullvadvpn-cbf5a1ce71893522af5e79ed4e655ae7e487dd30.zip
Add custom navigation controller
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj4
-rw-r--r--ios/MullvadVPN/CustomNavigationController.swift102
-rw-r--r--ios/MullvadVPN/SettingsNavigationController.swift2
3 files changed, 107 insertions, 1 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 4ccdcc0649..6f4e0914b3 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -53,6 +53,7 @@
581CBCEE229826FD00727D7F /* StaticTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581CBCED229826FD00727D7F /* StaticTableViewDataSource.swift */; };
58293FB125124117005D0BB5 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58293FB025124117005D0BB5 /* CustomTextField.swift */; };
58293FB3251241B4005D0BB5 /* CustomTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58293FB2251241B3005D0BB5 /* CustomTextView.swift */; };
+ 58293FB725138B88005D0BB5 /* CustomNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58293FB625138B88005D0BB5 /* CustomNavigationController.swift */; };
582AE3102440A6CA00E6733A /* AccountTokenInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582AE30F2440A6CA00E6733A /* AccountTokenInput.swift */; };
582AE3122440CA0D00E6733A /* AccountTokenInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582AE3112440CA0D00E6733A /* AccountTokenInputTests.swift */; };
582AE3132440CA2700E6733A /* AccountTokenInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582AE30F2440A6CA00E6733A /* AccountTokenInput.swift */; };
@@ -288,6 +289,7 @@
581CBCED229826FD00727D7F /* StaticTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticTableViewDataSource.swift; sourceTree = "<group>"; };
58293FB025124117005D0BB5 /* CustomTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextField.swift; sourceTree = "<group>"; };
58293FB2251241B3005D0BB5 /* CustomTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextView.swift; sourceTree = "<group>"; };
+ 58293FB625138B88005D0BB5 /* CustomNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomNavigationController.swift; sourceTree = "<group>"; };
582AE30F2440A6CA00E6733A /* AccountTokenInput.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountTokenInput.swift; sourceTree = "<group>"; };
582AE3112440CA0D00E6733A /* AccountTokenInputTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTokenInputTests.swift; sourceTree = "<group>"; };
582BB1AE229566420055B6EF /* SettingsCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsCell.swift; sourceTree = "<group>"; };
@@ -551,6 +553,7 @@
58AB9DEB2501040C006C5526 /* ConsentViewController.xib */,
5896AE83246D5889005B36CB /* CustomDateComponentsFormatting.swift */,
582BB1B0229569620055B6EF /* CustomNavigationBar.swift */,
+ 58293FB625138B88005D0BB5 /* CustomNavigationController.swift */,
58293FB025124117005D0BB5 /* CustomTextField.swift */,
58293FB2251241B3005D0BB5 /* CustomTextView.swift */,
58C6B35D22BBBFE3003C19AD /* Data+HexCoding.swift */,
@@ -1049,6 +1052,7 @@
58CCA01E2242787B004F3011 /* AccountTextField.swift in Sources */,
587AD7CA2342283900E93A53 /* Account.swift in Sources */,
58F840AF2464382C0044E708 /* KeychainItemRevision.swift in Sources */,
+ 58293FB725138B88005D0BB5 /* CustomNavigationController.swift in Sources */,
587425C12299833500CA2045 /* RootContainerViewController.swift in Sources */,
580EE20124B321D500F9D8A1 /* OperationProtocol.swift in Sources */,
5896AE84246D5889005B36CB /* CustomDateComponentsFormatting.swift in Sources */,
diff --git a/ios/MullvadVPN/CustomNavigationController.swift b/ios/MullvadVPN/CustomNavigationController.swift
new file mode 100644
index 0000000000..1a7e7bb49d
--- /dev/null
+++ b/ios/MullvadVPN/CustomNavigationController.swift
@@ -0,0 +1,102 @@
+//
+// CustomNavigationController.swift
+// MullvadVPN
+//
+// Created by pronebird on 17/09/2020.
+// Copyright © 2020 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+import UIKit
+
+enum NavigationPopTrigger {
+ case backButton
+ case interactiveGesture
+}
+
+protocol ConditionalNavigation: class {
+ func shouldPopNavigationItem(_ navigationItem: UINavigationItem, trigger: NavigationPopTrigger) -> Bool
+}
+
+class CustomNavigationController: UINavigationController, UINavigationBarDelegate {
+
+ private static let classInit: Void = {
+ swizzleMethod(
+ aClass: CustomNavigationController.self,
+ originalSelector: #selector(UINavigationBarDelegate.navigationBar(_:shouldPop:)),
+ newSelector: #selector(customNavigationController_navigationBar(_:shouldPop:))
+ )
+ }()
+
+ private var popGestureRecognizerDelegate: CustomPopGestureRecognizerDelegate?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ _ = Self.classInit
+
+ popGestureRecognizerDelegate = CustomPopGestureRecognizerDelegate(navigationController: self, systemGestureRecognizerDelegate: interactivePopGestureRecognizer?.delegate)
+
+ // Replace the system interactive gesture recognizer
+ interactivePopGestureRecognizer?.delegate = popGestureRecognizerDelegate
+ }
+
+ @objc dynamic func customNavigationController_navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
+ var shouldPop = true
+
+ if let conformingViewController = topViewController as? ConditionalNavigation {
+ shouldPop = conformingViewController.shouldPopNavigationItem(item, trigger: .backButton)
+ }
+
+ // Only call super implementation when we want to pop the controller
+ if shouldPop {
+ // Call super implementation
+ return customNavigationController_navigationBar(navigationBar, shouldPop: item)
+ } else {
+ return shouldPop
+ }
+ }
+}
+
+private class CustomPopGestureRecognizerDelegate: NSObject, UIGestureRecognizerDelegate {
+
+ private let systemGestureRecognizerDelegate: UIGestureRecognizerDelegate?
+ private weak var navigationController: UINavigationController?
+
+ init(navigationController: UINavigationController, systemGestureRecognizerDelegate: UIGestureRecognizerDelegate?) {
+ self.navigationController = navigationController
+ self.systemGestureRecognizerDelegate = systemGestureRecognizerDelegate
+ }
+
+ override func responds(to aSelector: Selector!) -> Bool {
+ if Self.instancesRespond(to: aSelector) {
+ return true
+ } else {
+ return systemGestureRecognizerDelegate?.responds(to: aSelector) ?? false
+ }
+ }
+
+ override func forwardingTarget(for aSelector: Selector!) -> Any? {
+ let shouldForward = systemGestureRecognizerDelegate?.responds(to: aSelector) ?? false
+
+ if shouldForward {
+ return systemGestureRecognizerDelegate
+ } else {
+ return nil
+ }
+ }
+
+ // MARK: - UIGestureRecognizerDelegate
+
+ func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
+ let shouldBegin = systemGestureRecognizerDelegate?.gestureRecognizerShouldBegin?(gestureRecognizer) ?? true
+
+ guard let navigationController = navigationController,
+ let topItem = navigationController.navigationBar.topItem,
+ let conformingViewController = navigationController.topViewController as? ConditionalNavigation else {
+ return shouldBegin
+ }
+
+ return shouldBegin && conformingViewController.shouldPopNavigationItem(topItem, trigger: .interactiveGesture)
+ }
+}
diff --git a/ios/MullvadVPN/SettingsNavigationController.swift b/ios/MullvadVPN/SettingsNavigationController.swift
index 87527b77cb..b582b78bca 100644
--- a/ios/MullvadVPN/SettingsNavigationController.swift
+++ b/ios/MullvadVPN/SettingsNavigationController.swift
@@ -9,7 +9,7 @@
import Foundation
import UIKit
-class SettingsNavigationController: UINavigationController {
+class SettingsNavigationController: CustomNavigationController {
override func viewDidLoad() {
super.viewDidLoad()