FMFullscreenPopGesture 是一个 UINavigationController 的扩展库,用于在 iOS 13+ 系统中启用全屏滑动返回手势。
本项目包含两个版本:
- Objective-C 版本 (v1.x) - 经典的 Objective-C 实现
- Swift 版本 (v2.x) - 全新的 Swift 重构版本
- ✅ 全屏滑动返回:从屏幕任意位置滑动返回,而非仅限边缘
- ✅ 按视图控制器控制:每个 ViewController 可独立配置
- ✅ 自定义判断逻辑:支持通过闭包动态控制返回行为
- ✅ 限制触发区域:可设置手势触发的最大左边距
- ✅ 导航栏自动管理:支持视图控制器级别的导航栏显示/隐藏
- ✅ RTL布局支持:完美支持从右到左的语言布局
- ✅ iOS 13.0+:最低支持 iOS 13.0
- ✅ Swift Package Manager:原生支持 SPM
- ✅ CocoaPods:传统 CocoaPods 支持
在 Xcode 中:
- 选择
File→Add Packages... - 输入仓库地址:
https://github.com/fengmingdev/FMFullscreenPopGesture.git - 选择版本
2.0.0或更高 - 点击
Add Package
或在 Package.swift 中添加:
dependencies: [
.package(url: "https://github.com/fengmingdev/FMFullscreenPopGesture.git", from: "2.0.0")
]在 Podfile 中添加:
pod 'FMFullscreenPopGesture', '~> 2.0'然后运行:
pod install在 Podfile 中添加:
pod 'FMFullscreenPopGesture', '~> 1.1'在 AppDelegate.swift 中导入并初始化:
import UIKit
import FMFullscreenPopGesture
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 初始化 FMFullscreenPopGesture(重要!)
FMFullscreenPopGesture.setup()
return true
}
}一旦完成初始化,所有 UINavigationController 都会自动支持全屏滑动返回!
import UIKit
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 什么都不需要做,已经支持全屏滑动返回了!
}
}import FMFullscreenPopGesture
class EditViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 完全禁用返回手势
fm_interactivePopDisabled = true
}
}import FMFullscreenPopGesture
class CustomViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 只允许在左边 50pt 内触发返回手势
fm_interactivePopMaxAllowedInitialDistanceToLeftEdge = 50
}
}import FMFullscreenPopGesture
class FormViewController: UIViewController {
private var hasUnsavedChanges = false
override func viewDidLoad() {
super.viewDidLoad()
// 使用闭包灵活控制返回行为
fm_shouldBeginBlock = { [weak self] in
guard let self = self else { return true }
// 有未保存的修改时,显示提示
if self.hasUnsavedChanges {
self.showSaveAlert()
return false // 不允许返回
}
return true // 允许返回
}
}
}import FMFullscreenPopGesture
class FullscreenViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 隐藏导航栏(仍然支持滑动返回)
fm_prefersNavigationBarHidden = true
}
}Objective-C 版本无需手动初始化,会自动生效。使用 fd_ 前缀的 API:
#import "UINavigationController+FDFullscreenPopGesture.h"
// 禁用返回手势
self.fd_interactivePopDisabled = YES;
// 限制触发区域
self.fd_interactivePopMaxAllowedInitialDistanceToLeftEdge = 50.0;
// 自定义返回逻辑
__weak typeof(self) weakSelf = self;
self.shouldBeginBlock = ^BOOL{
__strong typeof(weakSelf) strongSelf = weakSelf;
return !strongSelf.hasChanges;
};
// 隐藏导航栏
self.fd_prefersNavigationBarHidden = YES;| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fm_interactivePopDisabled |
Bool |
false |
是否禁用滑动返回手势 |
fm_prefersNavigationBarHidden |
Bool |
false |
是否隐藏导航栏 |
fm_interactivePopMaxAllowedInitialDistanceToLeftEdge |
CGFloat |
0 |
手势触发的最大左边距(0表示无限制) |
fm_shouldBeginBlock |
(() -> Bool)? |
nil |
自定义返回手势判断逻辑 |
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fm_fullscreenPopGestureRecognizer |
UIPanGestureRecognizer |
- | 全屏滑动返回手势识别器(只读) |
fm_viewControllerBasedNavigationBarAppearanceEnabled |
Bool |
true |
是否启用基于视图控制器的导航栏外观管理 |
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fd_interactivePopDisabled |
BOOL |
NO |
是否禁用滑动返回手势 |
fd_prefersNavigationBarHidden |
BOOL |
NO |
是否隐藏导航栏 |
fd_interactivePopMaxAllowedInitialDistanceToLeftEdge |
CGFloat |
0 |
手势触发的最大左边距 |
shouldBeginBlock |
BOOL(^)(void) |
nil |
自定义返回手势判断逻辑 |
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fd_fullscreenPopGestureRecognizer |
UIPanGestureRecognizer |
- | 全屏滑动返回手势识别器(只读) |
fd_viewControllerBasedNavigationBarAppearanceEnabled |
BOOL |
YES |
是否启用基于视图控制器的导航栏外观管理 |
| 特性 | Objective-C (v1.x) | Swift (v2.x) |
|---|---|---|
| API 前缀 | fd_ / shouldBeginBlock |
fm_ / fm_shouldBeginBlock |
| 初始化方式 | 自动(+load) |
手动调用 setup() |
| 类型安全 | 弱类型 | 强类型 |
| 闭包语法 | Block | Closure |
| 可选值 | nil 检查 |
Optional |
| 最低iOS版本 | iOS 8.0+ | iOS 13.0+ |
| Swift版本 | - | 5.5+ |
-
Method Swizzling
- 交换
UIViewController的viewWillAppear:和viewWillDisappear:方法 - 交换
UINavigationController的pushViewController:animated:方法
- 交换
-
Associated Objects
- 使用
objc_getAssociatedObject和objc_setAssociatedObject为 Extension 添加属性
- 使用
-
手势代理
- 创建自定义
UIPanGestureRecognizer - 通过 KVC 获取系统手势的内部 target 和 action
- 复用系统的交互式转场动画
- 创建自定义
-
导航栏管理
- 在
viewWillAppear:中注入导航栏显示/隐藏逻辑 - 支持视图控制器级别的导航栏外观控制
- 在
本仓库包含两个示例项目:
- Example - Objective-C 版本示例
- ExampleSwift - Swift 版本示例
运行示例项目:
cd ExampleSwift
pod install
open ExampleSwift.xcworkspace- iOS: 13.0+
- Swift: 5.5+
- Xcode: 13.0+
- iOS: 8.0+
- Xcode: 10.0+
FMFullscreenPopGesture 采用 MIT 许可证。详见 LICENSE 文件。
如有问题或建议,请:
- 提交 Issue
- 发送 Pull Request
Made with ❤️ by fengming