在 UINavigationController 中隐藏导航栏时不向后滑动

Posted

技术标签:

【中文标题】在 UINavigationController 中隐藏导航栏时不向后滑动【英文标题】:No Swipe Back when hiding Navigation Bar in 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,因为有些人说它有帮助但还没有让它工作。在这里寻找最简单、最优雅的解决方案。 【参考方案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的信息错误:***.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

尝试了其他解决方案:

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

    设置 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;

【讨论】:

请在发布答案之前阅读问题。问题是关于启用它,而不是禁用它。我们喜欢流行的手势。

以上是关于在 UINavigationController 中隐藏导航栏时不向后滑动的主要内容,如果未能解决你的问题,请参考以下文章

在 UINavigationController 内的 UITabBarcontroller 中添加 UINavigationController?

从嵌入在 UINavigationController 中的一个视图控制器到另一个 UINavigationController

(Swift) 在嵌套在 Main UINavigationController 中的 UINavigationController 和 UITabController 之间切换

关闭 UINavigationController 并呈现另一个 UINavigationController

带有主 UINavigationController 和详细 UINavigationController 的 UISplitViewcontroller

UINavigationController 标题和按钮