Skip to content

fengmingdev/FMFullscreenPopGesture

Repository files navigation

FMFullscreenPopGesture

Version Platform Swift License

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 支持

📦 安装

Swift 版本 (推荐)

Swift Package Manager

在 Xcode 中:

  1. 选择 FileAdd Packages...
  2. 输入仓库地址:https://github.com/fengmingdev/FMFullscreenPopGesture.git
  3. 选择版本 2.0.0 或更高
  4. 点击 Add Package

或在 Package.swift 中添加:

dependencies: [
    .package(url: "https://github.com/fengmingdev/FMFullscreenPopGesture.git", from: "2.0.0")
]

CocoaPods

Podfile 中添加:

pod 'FMFullscreenPopGesture', '~> 2.0'

然后运行:

pod install

Objective-C 版本

CocoaPods

Podfile 中添加:

pod 'FMFullscreenPopGesture', '~> 1.1'

🚀 使用方法

Swift 版本

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
    }
}

2. 基础使用(自动生效)

一旦完成初始化,所有 UINavigationController 都会自动支持全屏滑动返回

import UIKit

class MyViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // 什么都不需要做,已经支持全屏滑动返回了!
    }
}

3. 禁用返回手势

import FMFullscreenPopGesture

class EditViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // 完全禁用返回手势
        fm_interactivePopDisabled = true
    }
}

4. 限制触发区域

import FMFullscreenPopGesture

class CustomViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // 只允许在左边 50pt 内触发返回手势
        fm_interactivePopMaxAllowedInitialDistanceToLeftEdge = 50
    }
}

5. 自定义返回逻辑

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  // 允许返回
        }
    }
}

6. 隐藏导航栏

import FMFullscreenPopGesture

class FullscreenViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // 隐藏导航栏(仍然支持滑动返回)
        fm_prefersNavigationBarHidden = true
    }
}

Objective-C 版本

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;

📚 API 文档

Swift 版本

UIViewController 扩展

属性 类型 默认值 说明
fm_interactivePopDisabled Bool false 是否禁用滑动返回手势
fm_prefersNavigationBarHidden Bool false 是否隐藏导航栏
fm_interactivePopMaxAllowedInitialDistanceToLeftEdge CGFloat 0 手势触发的最大左边距(0表示无限制)
fm_shouldBeginBlock (() -> Bool)? nil 自定义返回手势判断逻辑

UINavigationController 扩展

属性 类型 默认值 说明
fm_fullscreenPopGestureRecognizer UIPanGestureRecognizer - 全屏滑动返回手势识别器(只读)
fm_viewControllerBasedNavigationBarAppearanceEnabled Bool true 是否启用基于视图控制器的导航栏外观管理

Objective-C 版本

UIViewController 扩展

属性 类型 默认值 说明
fd_interactivePopDisabled BOOL NO 是否禁用滑动返回手势
fd_prefersNavigationBarHidden BOOL NO 是否隐藏导航栏
fd_interactivePopMaxAllowedInitialDistanceToLeftEdge CGFloat 0 手势触发的最大左边距
shouldBeginBlock BOOL(^)(void) nil 自定义返回手势判断逻辑

UINavigationController 扩展

属性 类型 默认值 说明
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+

🎯 实现原理

核心技术

  1. Method Swizzling

    • 交换 UIViewControllerviewWillAppear:viewWillDisappear: 方法
    • 交换 UINavigationControllerpushViewController:animated: 方法
  2. Associated Objects

    • 使用 objc_getAssociatedObjectobjc_setAssociatedObject 为 Extension 添加属性
  3. 手势代理

    • 创建自定义 UIPanGestureRecognizer
    • 通过 KVC 获取系统手势的内部 target 和 action
    • 复用系统的交互式转场动画
  4. 导航栏管理

    • viewWillAppear: 中注入导航栏显示/隐藏逻辑
    • 支持视图控制器级别的导航栏外观控制

📱 示例项目

本仓库包含两个示例项目:

  • Example - Objective-C 版本示例
  • ExampleSwift - Swift 版本示例

运行示例项目:

cd ExampleSwift
pod install
open ExampleSwift.xcworkspace

⚙️ 系统要求

Swift 版本

  • iOS: 13.0+
  • Swift: 5.5+
  • Xcode: 13.0+

Objective-C 版本

  • iOS: 8.0+
  • Xcode: 10.0+

📄 许可证

FMFullscreenPopGesture 采用 MIT 许可证。详见 LICENSE 文件。

🙏 致谢

📞 联系方式

如有问题或建议,请:

  • 提交 Issue
  • 发送 Pull Request

🔗 相关链接


Made with ❤️ by fengming

About

Overview FDFullscreenPopGesture 添加侧滑监听

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •