【问题标题】:No Swipe Back when hiding Navigation Bar in UINavigationController在 UINavigationController 中隐藏导航栏时不向后滑动
【发布时间】:2014-09-02 19:38:44
【问题描述】:

我喜欢将您的视图嵌入到UINavigationController 中继承的滑动包。不幸的是,我似乎找不到隐藏NavigationBar 的方法,但仍然让触摸屏向后滑动gesture。我可以编写自定义手势,但我不喜欢而是依赖UINavigationController 向后滑动gesture

如果我在情节提要中取消选中它,则向后滑动不起作用

或者,如果我以编程方式隐藏它,同样的场景。

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.navigationController setNavigationBarHidden:YES animated:NO]; // and animated:YES
}

有没有办法隐藏顶部NavigationBar仍然可以滑动?

【问题讨论】:

  • 添加 UIGestureRecognizer 是否可以接受?实施起来轻而易举。
  • @LancelotdelaMare,我试图避免这种情况,因为它不会像 UINavigationController 向后滑动一样顺畅。我正在研究 UIScreenEdgePanGestureRecognizer,因为有些人说它有帮助但还没有让它工作。在这里寻找最简单、最优雅的解决方案。

标签: ios objective-c xcode uinavigationcontroller uigesturerecognizer


【解决方案1】:

一个可行的技巧是将interactivePopGestureRecognizerUINavigationController 代表设置为nil,如下所示:

[self.navigationController.interactivePopGestureRecognizer setDelegate:nil];

但在某些情况下,它可能会产生奇怪的效果。

【讨论】:

  • "当堆栈上只有一个视图控制器时,反复向后滑动可能会导致手势被识别,这反过来又会使 UI 处于停止识别的(我认为 UIKit 工程师出乎意料的)状态任何手势”
  • 另一种可能防止这种意外状态的方法是将其设置为一些低级对象(我使用了我的应用程序委托)并实现gestureRecognizerShouldBegin,如果navigationController 返回trueviewController 计数大于 0。
  • 虽然这可行,但我强烈建议不要这样做。破坏委托会导致罕见且难以识别的主线程块。原来它不是主线程块,而是@HorseT 所描述的。
  • 我的应用程序保存了委托句柄,然后在viewWillDisappear 中恢复它,到目前为止还没有遇到不良副作用。
  • !!!!强烈建议不要使用此解决方案,当反复使用滑动时出现奇怪的行为,背部被禁用,整个应用不再响应
【解决方案2】:

其他方法的问题

设置interactivePopGestureRecognizer.delegate = nil 会产生意想不到的副作用。

设置navigationController?.navigationBar.hidden = true 确实有效,但不允许隐藏导航栏中的更改。

最后,通常更好的做法是为导航控制器创建一个模型对象 UIGestureRecognizerDelegate。将其设置为 UINavigationController 堆栈中的控制器是导致 EXC_BAD_ACCESS 错误的原因。

完整解决方案

首先,将这个类添加到您的项目中:

class InteractivePopRecognizer: NSObject, UIGestureRecognizerDelegate {

    var navigationController: UINavigationController

    init(controller: UINavigationController) {
        self.navigationController = controller
    }

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return navigationController.viewControllers.count > 1
    }

    // This is necessary because without it, subviews of your top controller can
    // cancel out your gesture recognizer on the edge.
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

然后,将导航控制器的 interactivePopGestureRecognizer.delegate 设置为新的 InteractivePopRecognizer 类的实例。

var popRecognizer: InteractivePopRecognizer?

override func viewDidLoad() {
    super.viewDidLoad()
    setInteractiveRecognizer()
}

private func setInteractiveRecognizer() {
    guard let controller = navigationController else { return }
    popRecognizer = InteractivePopRecognizer(controller: controller)
    controller.interactivePopGestureRecognizer?.delegate = popRecognizer
}

享受没有副作用的隐藏导航栏,即使您的顶级控制器有表格、集合或滚动视图子视图,它也能正常工作。

【讨论】:

  • 很好的解决方案!
  • 最佳答案,谢谢!
  • @HunterMaximillionMonk 感谢您提供出色的解决方案。它就像一个魅力
  • 绝对是最佳答案!
  • 适用于 iOS 13.5、12.4.6 和 10.3.4。谢谢。
【解决方案3】:

在我的情况下,为了防止奇怪的影响

根视图控制器

override func viewDidLoad() {
    super.viewDidLoad()

    // Enable swipe back when no navigation bar
    navigationController?.interactivePopGestureRecognizer?.delegate = self
}

// UIGestureRecognizerDelegate
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    if let navVc = navigationController {
      return navVc.viewControllers.count > 1
    }
    return false
}

【讨论】:

  • 有时我在使用这个时会遇到 EXC_BAD_ACCESS
  • 对我来说,它不会使手势起作用,并且经常与 EXEC_BAD_ACCESS 崩溃
  • 记得将UIGestureRecognizerDelegate 添加到根视图控制器...在我的情况下,委托在比根视图控制器更晚的视图控制器中设置为 nil,所以当返回到根视图控制器时, gestureRecognizerShouldBegin 没有被调用。所以我把.delegate = self放在viewDidAppear()中。这解决了我的情况下的奇怪影响..干杯!
  • @AndreyGordeev 您能否详细说明EXEC_BAD_ACCESS 何时发生?
  • 这里有更多关于EXC_BAD_ACCESS的信息错误:stackoverflow.com/questions/28746123/…
【解决方案4】:

为 iOS 13.4 更新

iOS 13.4 打破了之前的解决方案,所以事情会变得很糟糕。看起来在 iOS 13.4 中,此行为现在由私有方法 _gestureRecognizer:shouldReceiveEvent: 控制(不要与 iOS 13.4 中添加的新公共 shouldReceive 方法混淆)。


我发现其他发布的解决方案覆盖委托或将其设置为 nil 会导致一些意外行为。

在我的情况下,当我在导航堆栈的顶部并尝试使用手势再弹出一个时,它会失败(如预期的那样),但随后尝试压入堆栈会开始导致奇怪的图形导航栏中的故障。这是有道理的,因为委托不仅仅用于处理在导航栏隐藏时是否阻止手势被识别,而且所有其他行为都被丢弃。

从我的测试来看,gestureRecognizer(_:, shouldReceiveTouch:) 似乎是原始委托实施的方法,用于在隐藏导航栏时阻止手势被识别,而不是gestureRecognizerShouldBegin(_:)。在其委托工作中实现 gestureRecognizerShouldBegin(_:) 的其他解决方案,因为缺少 gestureRecognizer(_:, shouldReceiveTouch:) 的实现将导致接收所有触摸的默认行为。

@Nathan Perry 的解决方案接近了,但如果没有实现 respondsToSelector(_:),向委托发送消息的 UIKit 代码将认为没有任何其他委托方法的实现,并且永远不会调用 forwardingTargetForSelector(_:) .

因此,在我们想要修改行为的一个特定场景中,我们控制 `gestureRecognizer(_:, shouldReceiveTouch:),否则将其他所有内容转发给委托。

class AlwaysPoppableNavigationController : UINavigationController {

    private var alwaysPoppableDelegate: AlwaysPoppableDelegate!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.alwaysPoppableDelegate = AlwaysPoppableDelegate(navigationController: self, originalDelegate: self.interactivePopGestureRecognizer!.delegate!)
        self.interactivePopGestureRecognizer!.delegate = self.alwaysPoppableDelegate
    }
}

private class AlwaysPoppableDelegate : NSObject, UIGestureRecognizerDelegate {

    weak var navigationController: AlwaysPoppableNavigationController?
    weak var originalDelegate: UIGestureRecognizerDelegate?

    init(navigationController: AlwaysPoppableNavigationController, originalDelegate: UIGestureRecognizerDelegate) {
        self.navigationController = navigationController
        self.originalDelegate = originalDelegate
    }

    // For handling iOS before 13.4
    @objc func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if let navigationController = navigationController, navigationController.isNavigationBarHidden && navigationController.viewControllers.count > 1 {
            return true
        }
        else if let originalDelegate = originalDelegate {
            return originalDelegate.gestureRecognizer!(gestureRecognizer, shouldReceive: touch)
        }
        else {
            return false
        }
    }

    // For handling iOS 13.4+
    @objc func _gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceiveEvent event: UIEvent) -> Bool {
        if let navigationController = navigationController, navigationController.isNavigationBarHidden && navigationController.viewControllers.count > 1 {
            return true
        }
        else if let originalDelegate = originalDelegate {
            let selector = #selector(_gestureRecognizer(_:shouldReceiveEvent:))
            if originalDelegate.responds(to: selector) {
                let result = originalDelegate.perform(selector, with: gestureRecognizer, with: event)
                return result != nil
            }
        }

        return false
    }

    override func responds(to aSelector: Selector) -> Bool {
        if #available(iOS 13.4, *) {
            // iOS 13.4+ does not need to override responds(to:) behavior, it only uses forwardingTarget
            return originalDelegate?.responds(to: aSelector) ?? false
        }
        else {
            if aSelector == #selector(gestureRecognizer(_:shouldReceive:)) {
                return true
            }
            else {
                return originalDelegate?.responds(to: aSelector) ?? false
            }
        }
    }

    override func forwardingTarget(for aSelector: Selector) -> Any? {
        if #available(iOS 13.4, *), aSelector == #selector(_gestureRecognizer(_:shouldReceiveEvent:)) {
            return nil
        }
        else {
            return self.originalDelegate
        }
    }
}

【讨论】:

  • 看起来您的解决方案是目前最好的。谢谢!
  • “但随后尝试压入堆栈将开始导致导航栏中出现奇怪的图形故障” - 我在这里感到困惑。我以为我们没有导航栏?这就是问题所在?在我的情况下,我嵌入了一个导航控制器作为没有导航栏的子视图控制器;包含的 VC 具有导航控件。所以我让包含的 VC 成为识别器的代表,只是做了gestureRecognizerShouldBegin: 的事情,它“似乎工作”。想知道我应该注意什么。
  • 这有内存泄漏,因为 navigationController 是 AlwaysPoppableDelegate 中的强引用。我已经编辑了代码以使其成为weak 参考。
  • 这个不错的解决方案在 iOS 13.4 中不再适用
  • @ChrisVasselli 真的很棒,谢谢!希望这将通过 App Store 审查的私有方法检查。
【解决方案5】:

你可以继承 UINavigationController 如下:

@interface CustomNavigationController : UINavigationController<UIGestureRecognizerDelegate>

@end

实施:

@implementation CustomNavigationController

- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated {
    [super setNavigationBarHidden:hidden animated:animated];
    self.interactivePopGestureRecognizer.delegate = self;
}

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

@end

【讨论】:

  • 使用这种方法会破坏UIPageViewController overscroll 中的弹出手势。
  • 我发现 viewController.count > 1 检查是必要的。如果用户尝试仅使用根 VC 向后滑动,则 UI 将在下一次 VC 推送时挂起。
【解决方案6】:

简单、无副作用的答案

虽然这里的大多数答案都很好,但它们似乎有意想不到的副作用(应用程序崩溃)或冗长。

我能想到的最简单但最实用的解决方案如下:

在您隐藏导航栏的 ViewController 中,

class MyNoNavBarViewController: UIViewController {
    
    // needed for reference when leaving this view controller
    var initialInteractivePopGestureRecognizerDelegate: UIGestureRecognizerDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // we will need a reference to the initial delegate so that when we push or pop.. 
        // ..this view controller we can appropriately assign back the original delegate
        initialInteractivePopGestureRecognizerDelegate = self.navigationController?.interactivePopGestureRecognizer?.delegate
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        // we must set the delegate to nil whether we are popping or pushing to..
        // ..this view controller, thus we set it in viewWillAppear()
        self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(true)

        // and every time we leave this view controller we must set the delegate back..
        // ..to what it was originally
        self.navigationController?.interactivePopGestureRecognizer?.delegate = initialInteractivePopGestureRecognizerDelegate
    }
}

其他答案建议仅将委托设置为零。向后滑动到导航堆栈上的初始视图控制器会导致禁用所有手势。也许是对 UIKit/UIGesture 开发者的某种疏忽。

同样,我在这里实现的一些答案导致了非标准的苹果导航行为(具体来说,允许在向后滑动的同时向上或向下滚动)。这些答案似乎也有点冗长,在某些情况下是不完整的。

【讨论】:

  • viewDidLoad() 不是捕获initialInteractivePopGestureRecognizerDelegate 的好地方,因为navigationController 在那里可能为零(尚未推入堆栈)。 viewWillAppear你隐藏导航栏的地方会更合适
  • 谢谢,以上所有答案中最好的和简单的解决方案
【解决方案7】:

Hunter Maximillion Monk's answer 的基础上,我为 UINavigationController 创建了一个子类,然后在我的故事板中为我的 UINavigationController 设置了自定义类。这两个类的最终代码如下所示:

InteractivePopRecognizer:

class InteractivePopRecognizer: NSObject {

    // MARK: - Properties

    fileprivate weak var navigationController: UINavigationController?

    // MARK: - Init

    init(controller: UINavigationController) {
        self.navigationController = controller

        super.init()

        self.navigationController?.interactivePopGestureRecognizer?.delegate = self
    }
}

extension InteractivePopRecognizer: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return (navigationController?.viewControllers.count ?? 0) > 1
    }

    // This is necessary because without it, subviews of your top controller can cancel out your gesture recognizer on the edge.
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

HiddenNavBarNavigationController:

class HiddenNavBarNavigationController: UINavigationController {

    // MARK: - Properties

    private var popRecognizer: InteractivePopRecognizer?

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()
        setupPopRecognizer()
    }

    // MARK: - Setup

    private func setupPopRecognizer() {
        popRecognizer = InteractivePopRecognizer(controller: self)
    }
}

故事板:

【讨论】:

    【解决方案8】:

    看起来@ChrisVasseli 提供的解决方案是最好的。我想在 Objective-C 中提供相同的解决方案,因为问题是关于 Objective-C(见标签)

    @interface InteractivePopGestureDelegate : NSObject <UIGestureRecognizerDelegate>
    
    @property (nonatomic, weak) UINavigationController *navigationController;
    @property (nonatomic, weak) id<UIGestureRecognizerDelegate> originalDelegate;
    
    @end
    
    @implementation InteractivePopGestureDelegate
    
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
    {
        if (self.navigationController.navigationBarHidden && self.navigationController.viewControllers.count > 1) {
            return YES;
        } else {
            return [self.originalDelegate gestureRecognizer:gestureRecognizer shouldReceiveTouch:touch];
        }
    }
    
    - (BOOL)respondsToSelector:(SEL)aSelector
    {
        if (aSelector == @selector(gestureRecognizer:shouldReceiveTouch:)) {
            return YES;
        } else {
            return [self.originalDelegate respondsToSelector:aSelector];
        }
    }
    
    - (id)forwardingTargetForSelector:(SEL)aSelector
    {
        return self.originalDelegate;
    }
    
    @end
    
    @interface NavigationController ()
    
    @property (nonatomic) InteractivePopGestureDelegate *interactivePopGestureDelegate;
    
    @end
    
    @implementation NavigationController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.interactivePopGestureDelegate = [InteractivePopGestureDelegate new];
        self.interactivePopGestureDelegate.navigationController = self;
        self.interactivePopGestureDelegate.originalDelegate = self.interactivePopGestureRecognizer.delegate;
        self.interactivePopGestureRecognizer.delegate = self.interactivePopGestureDelegate;
    }
    
    @end
    

    【讨论】:

    • 因为ObjC还没有死! ?
    • 这是正确的解决方案。任何其他不转发给原始委托的解决方案都是不正确的。
    【解决方案9】:

    我的解决方案是直接扩展UINavigationController类:

    import UIKit
    
    extension UINavigationController: UIGestureRecognizerDelegate {
    
        override open func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
    
            self.interactivePopGestureRecognizer?.delegate = self
        }
    
        public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            return self.viewControllers.count > 1
        }
    
    }
    

    这样,所有导航控制器都可以通过滑动关闭。

    【讨论】:

    • 奇怪的是,这会导致所有对属于任何导航控制器的 VC 的 viewDidAppear 调用都被忽略。
    【解决方案10】:

    Hunter Monk 的回答真的很牛逼,可惜在 iOS 13.3.1 中就不行了。

    我将解释另一种隐藏UINavigationBar 而不会丢失swipe to back gesture 的方法。 我已经在 iOS 13.3.1 和 12.4.3 上进行了测试,并且可以正常工作。

    您需要创建一个UINavigationController 的自定义类,并将该类设置为Storyboard 中的UINavigationController

    不要在Storyboard 上隐藏NavigationBar

    Storyboard 上的示例:

    最后,把这个:navigationBar.isHidden = true 放在 viewDidLoadCustomNavigationController 类中。

    请确保不要使用此方法setNavigationBarHidden(true, animated: true) 来隐藏NavigationBar

    import UIKit
    
    class CustomNavigationController: UINavigationController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            navigationBar.isHidden = true
        }
    }
    

    【讨论】:

    • 我已经在真机 iPhone 6S Plus 上使用iOS 13.4.1 进行了测试,然后滑动回来工作。
    • 不错的解决方案,在 iOS 14.5 (beta 2) 上测试并且仍然有效。请记住,preferredStatusBarStyle 将不再在视图控制器中调用。它必须由自定义导航控制器处理。
    【解决方案11】:

    您可以使用代理委托来完成。在构建导航控制器时,获取现有的委托。并将其传递给代理。然后使用forwardingTargetForSelector:将除gestureRecognizer:shouldReceiveTouch:之外的所有委托方法传递给现有委托

    设置:

    let vc = UIViewController(nibName: nil, bundle: nil)
    let navVC = UINavigationController(rootViewController: vc)
    let bridgingDelegate = ProxyDelegate()
    bridgingDelegate.existingDelegate = navVC.interactivePopGestureRecognizer?.delegate
    navVC.interactivePopGestureRecognizer?.delegate = bridgingDelegate
    

    代理委托:

    class ProxyDelegate: NSObject, UIGestureRecognizerDelegate {
        var existingDelegate: UIGestureRecognizerDelegate? = nil
    
        override func forwardingTargetForSelector(aSelector: Selector) -> AnyObject? {
            return existingDelegate
        }
    
        func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
            return true
        }  
    }
    

    【讨论】:

    • 这个答案是真正的Obj-C风格!
    • forwardingTargetForSelector 如果我知道过去的项目,我会节省很多时间。好东西!
    【解决方案12】:

    Xamarin 答案:

    在 ViewController 的类定义中实现 IUIGestureRecognizerDelegate 接口:

    public partial class myViewController : UIViewController, IUIGestureRecognizerDelegate
    

    在您的 ViewController 中添加以下方法:

    [Export("gestureRecognizerShouldBegin:")]
    public bool ShouldBegin(UIGestureRecognizer recognizer) {
      if (recognizer is UIScreenEdgePanGestureRecognizer && 
          NavigationController.ViewControllers.Length == 1) {
        return false;
      }
      return true;
    }
    

    在您的 ViewController 的 ViewDidLoad() 中添加以下行:

    NavigationController.InteractivePopGestureRecognizer.Delegate = this;
    

    【讨论】:

    • 大概这是在UINavigationController的根视图控制器中?当我尝试这个时,我得到了EXEC_BAD_ACCESS
    • 你能在根视图控制器上进行边缘平移吗?这应该是不可能的,因为当你在根 VC 时,你已经弹出了所有其他 VC,并且你的 Nav 的 VC 数组的长度应该是 1。
    • 崩溃发生在调用gestureRecognizerShouldBegin:之前。
    • 您可以在新问题或 Xamarin 论坛上发布您的 VC 代码吗?
    • 不,我没有。我想我会把它留到 0.1!
    【解决方案13】:

    我试过了,效果很好: How to hide Navigation Bar without losing slide-back ability

    这个想法是在你的 .h 中实现“UIGestureRecognizerDelegate” 并将其添加到您的 .m 文件中。

    - (void)viewWillAppear:(BOOL)animated {
    // hide nav bar
    [[self navigationController] setNavigationBarHidden:YES animated:YES];
    
    // enable slide-back
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        self.navigationController.interactivePopGestureRecognizer.delegate = self;
      }
    }
    
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
       return YES;  
    }
    

    【讨论】:

      【解决方案14】:

      这是我的解决方案: 我正在更改导航栏上的 alpha,但导航栏没有隐藏。 我所有的视图控制器都是我的 BaseViewController 的子类,我有:

          override func viewDidAppear(_ animated: Bool) {
          super.viewDidAppear(animated)
          navigationController?.navigationBar.alpha = 0.0
      }
      

      您也可以继承 UINavigationController 并将该方法放在那里。

      【讨论】:

        【解决方案15】:

        TLDR-没有任何副作用的解决方案:

        不要从故事板创建 UINavigationController,而是创建一个继承 UINavigationController 的自定义类并通过代码呈现它。

        class RootNavigationController: UINavigationController {
            override func viewDidLoad() {
                super.viewDidLoad()
                self.navigationBar.isHidden = true
            }
        }
        
        let rootNavVC = RootNavigationController(rootViewController: vc)
        if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            appDelegate.window?.rootViewController = rootNavVC
        }
        

        尝试了其他解决方案:

        1. interactivePopGestureRecognizer.delegate = nil 导致随机行为。

        2. 设置 interactivePopGestureRecognizer.delegate = self 然后在 viewDidAppear 或其他地方执行此操作。

          如果 navigationController?.viewControllers.count ?? 0 > 1 { navigationController?.interactivePopGestureRecognizer?.isEnabled = true } 别的 { navigationController?.interactivePopGestureRecognizer?.isEnabled = false }

        只要堆栈中有 1 个以上的视图控制器,它就可以正常工作。如果计数

        【讨论】:

          【解决方案16】:

          Some people 通过使用动画YES 调用setNavigationBarHidden 方法取得了成功。

          【讨论】:

          • 我没有运气。更新我的答案以涵盖此建议。
          【解决方案17】:

          在没有导航栏的视图控制器中,我使用

          open override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
          
            CATransaction.begin()
            UIView.animate(withDuration: 0.25, animations: { [weak self] in
              self?.navigationController?.navigationBar.alpha = 0.01
            })
            CATransaction.commit()
          }
          
          open override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            CATransaction.begin()
            UIView.animate(withDuration: 0.25, animations: { [weak self] in
              self?.navigationController?.navigationBar.alpha = 1.0
            })
            CATransaction.commit()
          }
          

          在交互式关闭期间,后退按钮会发光,这就是我隐藏它的原因。

          【讨论】:

            【解决方案18】:

            有一个非常简单的解决方案,我尝试过并且效果很好,它在 Xamarin.iOS 中,但也可以应用于本机:

                public override void ViewWillAppear(bool animated)
                {
                    base.ViewWillAppear(animated);
                    this.NavigationController.SetNavigationBarHidden(true, true);
                }
            
                public override void ViewDidAppear(bool animated)
                {
                    base.ViewDidAppear(animated);
                    this.NavigationController.SetNavigationBarHidden(false, false);
                    this.NavigationController.NavigationBar.Hidden = true;
                }
            
                public override void ViewWillDisappear(bool animated)
                {
                    base.ViewWillDisappear(animated);
                    this.NavigationController.SetNavigationBarHidden(true, false);
                }
            

            【讨论】:

              【解决方案19】:

              以下是当用户滑出 ViewController 时如何禁用手势识别器。您可以将其粘贴到 viewWillAppear() 或 ViewDidLoad() 方法上。

              if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
                  self.navigationController.interactivePopGestureRecognizer.enabled = NO;
              }
              

              【讨论】:

              • 请在发布答案之前阅读问题。问题是关于启用它,而不是禁用它。我们喜欢流行的手势。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-02-01
              • 2017-12-20
              相关资源
              最近更新 更多