• iOS-自定义导航栏后侧滑返回功能失效


    iPhone有一个回退按钮在所有的导航条上.这是一个简单的没有文字箭头.

    在一开始写项目的时候,就要做好一个准备,导航栏是自定义还是使用系统的,后期有什么改动,有什么比较特殊的需求、当然这些在更改需求的同时,很多东西都已经被改得面目全非了。

    完全自定义导航栏,在实际开发中,并不能满足特殊需求,因此更多情况下,还是需要配合系统导航栏自定义,从而达到我们想要的效果。当我们自定义返回按钮之后,就会出现系统的右滑Pop功能就失效了,这是其中的一个小问题,下面就跟大家分享一下我所了解到的:

    实现一个自定义按钮是简单的.类似这个设置controller 的navigationItem一个leftBarButtonItem.

     1 文/煜寒了(简书作者)
     2 原文链接:http://www.jianshu.com/p/349636eb3fca
     3 著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
     4 
     5 - (void)viewDidLoad
     6 {
     7   self.navigationItem.leftBarButtonItem = [self backButton];
     8 }
     9 
    10 - (UIBarButtonItem *)backButton
    11 {
    12   UIImage *image = [UIImage imageNamed:@"back_button"];
    13   CGRect buttonFrame = CGRectMake(0, 0, image.size.width, image.size.height);
    14 
    15   UIButton *button = [[UIButton alloc] initWithFrame:buttonFrame];
    16   [button addTarget:self action:@selector(backButtonPressed) forControlEvents:UIControlEventTouchUpInside];
    17   [button setImage:[UIImage imageNamed:normalImage] forState:UIControlStateNormal];
    18 
    19   UIBarButtonItem *item; = [[UIBarButtonItem alloc] initWithCustomView:button];
    20 
    21   return item;
    22 }
    View Code

    但是这样在iOS7上 pop手势交互就不好使了.我发现了一个轻松解决的办法.通过我的beta测试者,我收到了很多关于pop手势的崩溃日志.我发现在栈中推入一个controller后,快速向左平滑,将会引起崩溃.换句话说,如果用户在推入还在进行的时候立即去点击返回.那么导航控制器就秀逗了.我在调试日志里面发现这些:
    nested pop animation can result in corrupted navigation bar

    经过几个小时的奋斗和尝试,我发现可以缓解这个错误:设置手势的delegate为这个导航控制器就像Stuart Hall在他的帖子说的那样,分配了一个手势交互行为的委托在自定义按钮显示的时候.然后,当用户快速点击退出的时候,控制器因为手势发送了一个消息在本身已经被销毁的时候.我的解决方案是简单的让NavigationController自己成为响应的接受者.最好用一个UINavigationController的子类.
     1 文/煜寒了(简书作者)
     2 原文链接:http://www.jianshu.com/p/349636eb3fca
     3 著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
     4 
     5 @interface CBNavigationController : UINavigationController <UIGestureRecognizerDelegate>
     6 @end
     7 
     8 @implementation CBNavigationController
     9 
    10 - (void)viewDidLoad
    11 {
    12   __weak CBNavigationController *weakSelf = self;
    13 
    14   if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
    15   {
    16     self.interactivePopGestureRecognizer.delegate = weakSelf;
    17   }
    18 }
    19 
    20 @end
    View Code

    在转场/过渡的时候禁用 interactivePopGestureRecognizer当用户在转场的时候触发一个后退手势,则各种事件又凑一块了.导航栈内又成了混乱的.我的解决办法是,转场效果的过程中禁用手势识别,当新的视图控制器加载完成后再启用.再次建议使用UINavigationController的子类操作.
     1 文/煜寒了(简书作者)
     2 原文链接:http://www.jianshu.com/p/349636eb3fca
     3 著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
     4 
     5 @interface CBNavigationController : UINavigationController <UINavigationControllerDelegate, UIGestureRecognizerDelegate>
     6 @end
     7 
     8 @implementation CBNavigationController
     9 
    10 - (void)viewDidLoad
    11 {
    12   __weak CBNavigationController *weakSelf = self;
    13 
    14   if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
    15   {
    16     self.interactivePopGestureRecognizer.delegate = weakSelf;
    17     self.delegate = weakSelf;
    18   }
    19 }
    20 
    21 // Hijack the push method to disable the gesture
    22 
    23 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    24 {
    25   if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
    26     self.interactivePopGestureRecognizer.enabled = NO;
    27 
    28   [super pushViewController:viewController animated:animated];
    29 }
    30 
    31 #pragma mark UINavigationControllerDelegate
    32 
    33 - (void)navigationController:(UINavigationController *)navigationController
    34        didShowViewController:(UIViewController *)viewController
    35                     animated:(BOOL)animate
    36 {
    37   // Enable the gesture again once the new controller is shown
    38 
    39   if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
    40     self.interactivePopGestureRecognizer.enabled = YES;
    41 }
    42 
    43 
    44 @end
    View Code

    2015-07-21 更新 解决左滑手势冲突和不灵敏的问题
     1 文/煜寒了(简书作者)
     2 原文链接:http://www.jianshu.com/p/349636eb3fca
     3 著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
     4 
     5 -(UIViewController *)popViewControllerAnimated:(BOOL)animated {
     6 
     7     return [super popViewControllerAnimated:YES];
     8 }
     9 
    10 #pragma mark UINavigationControllerDelegate
    11 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    12     if ([self.childViewControllers count] == 1) {
    13         return NO;
    14     }
    15     return YES;
    16 }
    17 
    18 // 我们差不多能猜到是因为手势冲突导致的,那我们就先让 ViewController 同时接受多个手势吧。
    19 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    20 {
    21     return YES;
    22 }
    23 //运行试一试,两个问题同时解决,不过又发现了新问题,手指在滑动的时候,被 pop 的 ViewController 中的 UIScrollView 会跟着一起滚动,这个效果看起来就很怪(知乎日报现在就是这样的效果),而且也不是原始的滑动返回应有的效果,那么就让我们继续用代码来解决吧
    24 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    25 {
    26     return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];
    27 }
    28 
    29 -(UIViewController *)popViewControllerAnimated:(BOOL)animated {
    30 
    31     return [super popViewControllerAnimated:YES];
    32 }
    33 
    34 #pragma mark UINavigationControllerDelegate
    35 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    36     if ([self.childViewControllers count] == 1) {
    37         return NO;
    38     }
    39     return YES;
    40 }
    41 
    42 // 我们差不多能猜到是因为手势冲突导致的,那我们就先让 ViewController 同时接受多个手势吧。
    43 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    44 {
    45     return YES;
    46 }
    47 //运行试一试,两个问题同时解决,不过又发现了新问题,手指在滑动的时候,被 pop 的 ViewController 中的 UIScrollView 会跟着一起滚动,这个效果看起来就很怪(知乎日报现在就是这样的效果),而且也不是原始的滑动返回应有的效果,那么就让我们继续用代码来解决吧
    48 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    49 {
    50     return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];
    51 }
    View Code
  • 相关阅读:
    spoj694 DISUBSTR
    poj3261 Milk Patterns
    poj1743 Musical Theme
    Hdu1403 Longest Common Substring
    bzoj3779 重组病毒
    bzoj3083 遥远的国度
    bzoj3514 Codechef MARCH14 GERALD07加强版
    PAT 乙级 1027 打印沙漏(20) C++版
    PAT 乙级 1060 爱丁顿数(25) C++版
    windows编程之窗口抖动
  • 原文地址:https://www.cnblogs.com/fengmin/p/5318817.html
Copyright © 2020-2023  润新知