iOS学习笔记-095.彩票10——滑动移除控制器全屏实现

来源:互联网 发布:宾馆网络解决方案 编辑:程序博客网 时间:2024/05/16 12:55

  • 彩票10滑动移除控制器全屏实现
    • 一图示
    • 二分析
    • 三非全屏滑动删除的处理方式
    • 四全屏滑动删除的处理方式 1 KVC
    • 五全屏滑动删除的处理方式 2 delegate

彩票10——滑动移除控制器全屏实现

一、图示

这里写图片描述


二、分析

原本系统有滑动删除的,但是我们添加了放回按钮以后没有了,那么这下就尴尬了吧。那么我们就行来实现一下。

其实我们只需要把 系统手势的代理设置为nil 就可以实现这样的功能了,但是这用实现,我们是能滑动左边的并且不包含导航条。并且会产生一个bug,就是如果我们在根控制器上滑动了,那么我们就 push 不了其他控制器了。那么怎么解决呢,其实解决方式很简单,我们一开始记住我们的代理,然后在 did 控制器的时候,我们判断一下,当前的控制器是不是根控制器,如果是还原,不是赋值为nil。

另外的处理方式,就是我们自己添加一个滑动手势,然后我们使用系统的处理方法和targer来处理这个手势就行了。


三、非全屏滑动删除的处理方式

这种方式处理的结果就是只能从左侧滑动时删除。

这种方式需要添加 UINavigationControllerDelegate 代理

////  QWMNavigationController.m//  03_UIView79_彩票////  Created by 杞文明 on 17/8/13.//  Copyright © 2017年 杞文明. All rights reserved.//#import "QWMNavigationController.h"#import <objc/runtime.h>@interface QWMNavigationController ()<UINavigationControllerDelegate>/** 系统手势代理 */@property (nonatomic, strong) id popGesture;@end@implementation QWMNavigationController········-(void)viewDidLoad{    [super viewDidLoad];    self.popGesture = self.interactivePopGestureRecognizer.delegate;    self.delegate = self;}// 解决如果在根控制器上滑动了,不能删除的情况-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{    if(self.viewControllers[0]==viewController){//根控制器        self.interactivePopGestureRecognizer.delegate = self.popGesture;    }else{        // 清空手势代理就能实现滑动返回, iOS6不支持        self.interactivePopGestureRecognizer.delegate = nil;    }}·····@end

四、全屏滑动删除的处理方式 1 —— KVC

这种方式的处理就是,自己添加一个滑动手势 UIPanGestureRecognizer 这个手势的 targetaction,使用系统手势使用的。

那么我们使用

NSLog(@"%@",self.interactivePopGestureRecognizer);

打印一下系统手势的信息
如下

<UIScreenEdgePanGestureRecognizer: 0x7fd258d1ab20;     state = Possible;     delaysTouchesBegan = YES;     view = <UILayoutContainerView 0x7fd258d198a0>;     target= <       (action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fd258e1be20>)    >>

通过上面的信息,我们可以知道 我们 添加的手势的 action 就是 handleNavigationTransition: 方法。
但是我们 target 我们还没办法拿到。

我们使用 oc 中的 runtime 机制,来获取我们的属性名称,然后使用 KVC 来获取我们的 target

我们使用 runtime 机制打印出 UIGestureRecognizer 里面的属性

// oc  runtime 机制 只能动态获取当前类的成员属性,不能获取其子类,或者父类的属性// __unsafe_unretained Class  要获取哪个类的成员属性// unsigned int *outCount  获取Class 下面的所有成员属性的个数unsigned int outCount;Ivar * ivars = class_copyIvarList([UIGestureRecognizer class], &outCount);for (int i=0; i<outCount; i++) {    NSString * name = @(ivar_getName(ivars[i]));    NSLog(@"%@",name);}

打印结果

2017-08-26 16:21:36.885 03_UIView79_彩票[12961:57679] _gestureFlags2017-08-26 16:21:36.885 03_UIView79_彩票[12961:57679] _targets2017-08-26 16:21:36.885 03_UIView79_彩票[12961:57679] _delayedTouches2017-08-26 16:21:36.886 03_UIView79_彩票[12961:57679] _delayedPresses2017-08-26 16:21:36.886 03_UIView79_彩票[12961:57679] _view2017-08-26 16:21:36.886 03_UIView79_彩票[12961:57679] _lastTouchTimestamp2017-08-26 16:21:36.887 03_UIView79_彩票[12961:57679] _state2017-08-26 16:21:36.887 03_UIView79_彩票[12961:57679] _allowedTouchTypes2017-08-26 16:21:36.887 03_UIView79_彩票[12961:57679] _initialTouchType2017-08-26 16:21:36.888 03_UIView79_彩票[12961:57679] _internalActiveTouches2017-08-26 16:21:36.888 03_UIView79_彩票[12961:57679] _forceClassifier2017-08-26 16:21:36.888 03_UIView79_彩票[12961:57679] _requiredPreviewForceState2017-08-26 16:21:36.888 03_UIView79_彩票[12961:57679] _touchForceObservable2017-08-26 16:21:36.888 03_UIView79_彩票[12961:57679] _touchForceObservableAndClassifierObservation2017-08-26 16:21:36.888 03_UIView79_彩票[12961:57679] _forceTargets2017-08-26 16:21:36.888 03_UIView79_彩票[12961:57679] _forcePressCount2017-08-26 16:21:36.889 03_UIView79_彩票[12961:57679] _beganObservable2017-08-26 16:21:36.889 03_UIView79_彩票[12961:57679] _failureRequirements2017-08-26 16:21:36.889 03_UIView79_彩票[12961:57679] _failureDependents2017-08-26 16:21:36.889 03_UIView79_彩票[12961:57679] _delegate2017-08-26 16:21:36.889 03_UIView79_彩票[12961:57679] _allowedPressTypes2017-08-26 16:21:36.890 03_UIView79_彩票[12961:57679] _gestureEnvironment

我们可以看到有一个 —targets 属性,然后我们 通过 KVC 获取这个值,然后打印一下。

UIScreenEdgePanGestureRecognizer * gest = self.interactivePopGestureRecognizer;id targets = [gest valueForKeyPath:@"_targets"];NSLog(@"%@",targets);

结果

(    "(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fb3c9d0b5d0>)")

我们可以看到 这是一个数组,但是我们还是没法知道我么的 target。

我们调试一下看一下。我们会发现原来属性叫 _target

这里写图片描述

现在我们已经知道属性名了,那么我么既可以通过 KVC 来获取了

// 通过 KVC 方式获取 _target    id target = [targets[0] valueForKeyPath:@"_target"];

完整如下

////  QWMNavigationController.m//  03_UIView79_彩票////  Created by 杞文明 on 17/8/13.//  Copyright © 2017年 杞文明. All rights reserved.//#import "QWMNavigationController.h"#import <objc/runtime.h>@interface QWMNavigationController ()<UINavigationControllerDelegate,UIGestureRecognizerDelegate>/** 系统手势代理 */@property (nonatomic, strong) id popGesture;@end@implementation QWMNavigationController.......-(void)viewDidLoad{    [super viewDidLoad];    UIScreenEdgePanGestureRecognizer * gest = self.interactivePopGestureRecognizer;    //KVC获取 _targets     NSArray * targets = [gest valueForKeyPath:@"_targets"];    // 通过 KVC 方式获取 _target    id target = [targets[0] valueForKeyPath:@"_target"];    //添加滑动手势    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:target action:@selector(handleNavigationTransition:)];    [self.view addGestureRecognizer:pan];}@end.......

五、全屏滑动删除的处理方式 2 ——delegate

这种处理方式,其实有原因的,我们在创建一个手势的时候,我们发现,我们添加的 target 和 delegate 是一样的,那么系统的应该也是一样的。

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];pan.delegate = self;

所以需要的 target 其实就是delegate 。

id target = self.interactivePopGestureRecognizer.delegate;

但是如果我们这个添加了 会出现上面我们出现过的bug : 就是如果我们在根控制器上滑动了,那么我们就 push 不了其他控制器了.

那么怎么解决呢?

我们可以添加 UIGestureRecognizerDelegate 代理。手指开始时去判断是不是根控制器,如果是的话,那么我们禁止手势,如果不是我们响应手势

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{    return self.viewControllers.count > 1;}

完整代码如下

////  QWMNavigationController.m//  03_UIView79_彩票////  Created by 杞文明 on 17/8/13.//  Copyright © 2017年 杞文明. All rights reserved.//#import "QWMNavigationController.h"#import <objc/runtime.h>@interface QWMNavigationController ()<UINavigationControllerDelegate,UIGestureRecognizerDelegate>/** 系统手势代理 */@property (nonatomic, strong) id popGesture;@end@implementation QWMNavigationController-(void)viewDidLoad{    [super viewDidLoad];    id target = self.interactivePopGestureRecognizer.delegate;    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:target action:@selector(handleNavigationTransition:)];    [self.view addGestureRecognizer:pan];    pan.delegate = self;}-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{    return self.viewControllers.count > 1;}@end
阅读全文
0 0
原创粉丝点击