diff --git a/ACKategories.xcodeproj/project.pbxproj b/ACKategories.xcodeproj/project.pbxproj index 33e0004d..3eff084e 100644 --- a/ACKategories.xcodeproj/project.pbxproj +++ b/ACKategories.xcodeproj/project.pbxproj @@ -99,6 +99,7 @@ 69FA5FBC23C868A900B44BCD /* AppFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FA5FAB23C868A900B44BCD /* AppFlowCoordinator.swift */; }; 69FA5FBD23C868A900B44BCD /* ModalFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69FA5FAC23C868A900B44BCD /* ModalFlowCoordinator.swift */; }; 69FA5FC223C8690A00B44BCD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 69FA5FC123C8690A00B44BCD /* LaunchScreen.storyboard */; }; + 6A72B2222B1A15AC00A59EDD /* BackGesture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A72B2212B1A15AC00A59EDD /* BackGesture.swift */; }; 88EDD90425B8252E00207987 /* GradientViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88EDD90325B8252E00207987 /* GradientViewController.swift */; }; /* End PBXBuildFile section */ @@ -244,6 +245,7 @@ 69FA5FAB23C868A900B44BCD /* AppFlowCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppFlowCoordinator.swift; sourceTree = ""; }; 69FA5FAC23C868A900B44BCD /* ModalFlowCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModalFlowCoordinator.swift; sourceTree = ""; }; 69FA5FC123C8690A00B44BCD /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 6A72B2212B1A15AC00A59EDD /* BackGesture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackGesture.swift; sourceTree = ""; }; 88EDD90325B8252E00207987 /* GradientViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -370,6 +372,7 @@ 69E0A5F62AFD10BE00C8E8D9 /* PropertyWrappers */, 69E0A5FE2AFD10BE00C8E8D9 /* RandomExtensions */, 69E0A6032AFD10BE00C8E8D9 /* SwiftUIExtensions */, + 6A72B2212B1A15AC00A59EDD /* BackGesture.swift */, ); path = ACKategories; sourceTree = ""; @@ -847,6 +850,7 @@ 69ACD6F72AFD133A0021127B /* UIStackViewExtensions.swift in Sources */, 69ACD6F82AFD133A0021127B /* UIView+Spacer.swift in Sources */, 69ACD6F92AFD133A0021127B /* UIViewController+Children.swift in Sources */, + 6A72B2222B1A15AC00A59EDD /* BackGesture.swift in Sources */, 69ACD6FA2AFD133A0021127B /* UIViewController+FrontMost.swift in Sources */, 69ACD6FB2AFD133A0021127B /* UIViewExtensions.swift in Sources */, 69ACD6FC2AFD133A0021127B /* UserDefaultsExtensions.swift in Sources */, diff --git a/CHANGELOG.md b/CHANGELOG.md index 1db17e71..6f5901c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ ``` ## Next -- Support tvOS & watchOS, use single multiplatform target for Carthage ([#14%](https://github.com/AckeeCZ/ACKategories/pull/140), kudos to @olejnjak) +- Add helper function for easier back gesture setup ([#141](https://github.com/AckeeCZ/ACKategories/pull/141), kudos to @leinhauplk) +- Support tvOS & watchOS, use single multiplatform target for Carthage ([#140](https://github.com/AckeeCZ/ACKategories/pull/140), kudos to @olejnjak) - Add helpers for `SwiftUI.EdgeInsets` ([#138](https://github.com/AckeeCZ/ACKategories/pull/138), kudos to @olejnjak) - Bump deployment target to iOS 12 ([#137](https://github.com/AckeeCZ/ACKategories/pull/137), kudos to @olejnjak) - Add Font modifier for SwiftUI fonts ([#134](https://github.com/AckeeCZ/ACKategories/pull/134), kudos to @leinhauplk) diff --git a/Sources/ACKategories/BackGesture.swift b/Sources/ACKategories/BackGesture.swift new file mode 100644 index 00000000..731f1d08 --- /dev/null +++ b/Sources/ACKategories/BackGesture.swift @@ -0,0 +1,56 @@ +#if os(iOS) +import UIKit + +private class BackGestureDelegate: NSObject { + // MARK: - Private properties + + private weak var navigationController: UINavigationController? + + // MARK: Initializers + + init( + navigationController: UINavigationController + ) { + super.init() + self.navigationController = navigationController + } +} + +// MARK: - UIGestureRecognizerDelegate +extension BackGestureDelegate: UIGestureRecognizerDelegate { + func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + navigationController.map { $0.viewControllers.count > 1 } ?? false + } +} + +extension UINavigationController { + private enum Keys { + static var backGestureDelegate: UInt8 = 0 + } + + private var backGestureDelegate: BackGestureDelegate { + if let delegate = objc_getAssociatedObject(self, &Keys.backGestureDelegate) as? BackGestureDelegate { + return delegate + } + + let delegate = BackGestureDelegate(navigationController: self) + objc_setAssociatedObject( + self, + &Keys.backGestureDelegate, + delegate, + .OBJC_ASSOCIATION_RETAIN + ) + return delegate + } + + /// Add custom interactivePopGestureRecognizer delegate so it works even with hidden navigationBar + public func setupCustomBackGestureDelegate() { + assert(isViewLoaded, "View needs to be already loaded") + assert( + interactivePopGestureRecognizer != nil, + "Cannot install gesture delegate on nil recognizer" + ) + interactivePopGestureRecognizer?.delegate = backGestureDelegate + } +} +#endif