自定义全屏返回手势
使用分类,入侵性低,直接拖动到项目中,一句代码都不用写,自动生效
演示效果
目录结构
原理
.h文件
/// 自定义全屏拖拽返回手势
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *popGestureRecognizer;
定义单个控制器取消手势方法
- (void)cancleHMFullScreenPopGesRec:(BOOL)cancle;
.m文件
一、引入头文件#import <objc/runtime.h>
二、定义手势代理类
// 判断是否是根控制器,如果是,取消手势
if (self.navigationController.viewControllers.count <= 1) {
return NO;
}
// 如果正在转场动画,取消手势
if ([[self.navigationController valueForKey:@"_isTransitioning"] boolValue]) {
return NO;
}
// 判断手指移动方向
CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
if (translation.x <= 0) {
return NO;
}
if (self.isCancle) {
return NO;
}
return YES;
}
三、在NCPopGestureRecognizer的类实现中
在load方法中交换navVC的push方法和自定义的方法实例
+ (void)load {
Method originalMethod = class_getInstanceMethod([self class], @selector(pushViewController:animated:));
Method swizzledMethod = class_getInstanceMethod([self class], @selector(hm_pushViewController:animated:));
method_exchangeImplementations(originalMethod, swizzledMethod);
}
取消的方法调用上边自定义类的属性赋值
- (void)cancleHMFullScreenPopGesRec:(BOOL)cancle {
[self hm_fullScreenPopGestureRecognizerDelegate].isCancle = cancle;
}
自定义push方法和手势
根据kvc取值拿到 target 和action添加到自定义手势
并禁用系统交换手势,设置手势代理为自定义类
- (void)hm_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.popGestureRecognizer]) {
[self.interactivePopGestureRecognizer.view addGestureRecognizer:self.popGestureRecognizer];
NSArray *targets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
id internalTarget = [targets.firstObject valueForKey:@"target"];
SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:");
self.popGestureRecognizer.delegate = [self hm_fullScreenPopGestureRecognizerDelegate];
[self.popGestureRecognizer addTarget:internalTarget action:internalAction];
// 禁用系统的交互手势
self.interactivePopGestureRecognizer.enabled = NO;
}
if (![self.viewControllers containsObject:viewController]) {
[self hm_pushViewController:viewController animated:animated];
}
}
用runtime给分类添加属性绑定
- (HMFullScreenPopGestureRecognizerDelegate *)hm_fullScreenPopGestureRecognizerDelegate {
HMFullScreenPopGestureRecognizerDelegate *delegate = objc_getAssociatedObject(self, _cmd);
if (!delegate) {
delegate = [[HMFullScreenPopGestureRecognizerDelegate alloc] init];
delegate.navigationController = self;
objc_setAssociatedObject(self, _cmd, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return delegate;
}
- (UIPanGestureRecognizer *)popGestureRecognizer {
UIPanGestureRecognizer *panGestureRecognizer = objc_getAssociatedObject(self, _cmd);
if (panGestureRecognizer == nil) {
panGestureRecognizer = [[UIPanGestureRecognizer alloc] init];
panGestureRecognizer.maximumNumberOfTouches = 1;
objc_setAssociatedObject(self, _cmd, panGestureRecognizer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return panGestureRecognizer;
}
```自定义全屏返回手势
> 代码地址如下:<br>http://www.demodashi.com/demo/11971.html
> 注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?