简体   繁体   English

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

[英]No Swipe Back when hiding Navigation Bar in UINavigationController

I love the swipe pack thats inherited from embedding your views in a UINavigationController .我喜欢从将视图嵌入UINavigationController继承而来的滑动包。 Unfortunately i cannot seem to find a way to hide the NavigationBar but still have the touch pan swipe back gesture .不幸的是,我似乎找不到隐藏NavigationBar的方法,但仍然有触摸平移向后滑动gesture I can write custom gestures but I prefer not to and to rely on the UINavigationController back swipe gesture instead.我可以编写自定义手势,但我不喜欢而是依赖UINavigationController向后滑动gesture

if I uncheck it in the storyboard, the back swipe doesn't work如果我在情节提要中取消选中它,则向后滑动不起作用

在此处输入图像描述

alternatively if I programmatically hide it, the same scenario.或者,如果我以编程方式隐藏它,同样的场景。

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

Is there no way to hide the top NavigationBar and still have the swipe?有没有办法隐藏顶部NavigationBar并且仍然可以滑动?

A hack that is working is to set the interactivePopGestureRecognizer 's delegate of the UINavigationController to nil like this:一个有效的技巧是将UINavigationControllerinteractivePopGestureRecognizer的委托设置为nil ,如下所示:

[self.navigationController.interactivePopGestureRecognizer setDelegate:nil];

But in some situations it could create strange effects.但在某些情况下,它可能会产生奇怪的效果。

Problems with Other Methods其他方法的问题

Setting the interactivePopGestureRecognizer.delegate = nil has unintended side-effects.设置interactivePopGestureRecognizer.delegate = nil会产生意想不到的副作用。

Setting navigationController?.navigationBar.hidden = true does work, but does not allow your change in navigation bar to be hidden.设置navigationController?.navigationBar.hidden = true确实有效,但不允许隐藏导航栏中的更改。

Lastly, it's generally better practice to create a model object that is the UIGestureRecognizerDelegate for your navigation controller.最后,为导航控制器创建一个模型对象UIGestureRecognizerDelegate通常是更好的做法。 Setting it to a controller in the UINavigationController stack is what is causing the EXC_BAD_ACCESS errors.将其设置为UINavigationController堆栈中的控制器是导致EXC_BAD_ACCESS错误的原因。

Full Solution完整的解决方案

First, add this class to your project:首先,将此类添加到您的项目中:

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
    }
}

Then, set your navigation controller's interactivePopGestureRecognizer.delegate to an instance of your new InteractivePopRecognizer class.然后,将导航控制器的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
}

Enjoy a hidden navigation bar with no side effects, that works even if your top controller has table, collection, or scroll view subviews.享受一个没有副作用的隐藏导航栏,即使您的顶部控制器有表格、集合或滚动视图子视图,它也能正常工作。

In my case, to prevent strange effects就我而言,为了防止奇怪的影响

Root view controller根视图控制器

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
}

Updated for iOS 13.4为 iOS 13.4 更新

iOS 13.4 broke the previous solution, so things are gonna get ugly. iOS 13.4 打破了之前的解决方案,所以事情会变得很糟糕。 It looks like in iOS 13.4 this behavior is now controlled by a private method _gestureRecognizer:shouldReceiveEvent: (not to be confused with the new public shouldReceive method added in iOS 13.4).看起来在 iOS 13.4 中,此行为现在由私有方法_gestureRecognizer:shouldReceiveEvent:控制(不要与 iOS 13.4 中添加的新公共shouldReceive方法混淆)。


I found that other posted solutions overriding the delegate, or setting it to nil caused some unexpected behavior.我发现其他发布的解决方案覆盖了委托,或者将其设置为 nil 会导致一些意外行为。

In my case, when I was on the top of the navigation stack and tried to use the gesture to pop one more, it would fail (as expected), but subsequent attempts to push onto the stack would start to cause weird graphical glitches in the navigation bar.在我的情况下,当我在导航堆栈的顶部并尝试使用手势再弹出一个时,它会失败(如预期的那样),但随后尝试压入堆栈会开始导致奇怪的图形故障导航栏。 This makes sense, because the delegate is being used to handle more than just whether or not to block the gesture from being recognized when the navigation bar is hidden, and all that other behavior was being thrown out.这是有道理的,因为代理被用来处理的不仅仅是当导航栏隐藏时是否阻止手势被识别,以及所有其他行为都被抛出。

From my testing, it appears that gestureRecognizer(_:, shouldReceiveTouch:) is the method that the original delegate is implementing to block the gesture from being recognized when the navigation bar is hidden, not gestureRecognizerShouldBegin(_:) .从我的测试来看, gestureRecognizer(_:, shouldReceiveTouch:)似乎是原始委托在隐藏导航栏时阻止手势被识别的方法,而不是gestureRecognizerShouldBegin(_:) Other solutions that implement gestureRecognizerShouldBegin(_:) in their delegate work because the lack of an implementation of gestureRecognizer(_:, shouldReceiveTouch:) will cause the default behavior of receiving all touches.其他在其委托工作中实现gestureRecognizerShouldBegin(_:)的解决方案,因为缺少gestureRecognizer(_:, shouldReceiveTouch:)的实现将导致接收所有触摸的默认行为。

@Nathan Perry's solution gets close, but without an implementation of respondsToSelector(_:) , the UIKit code that sends messages to the delegate will believe there is no implementation for any of the other delegate methods, and forwardingTargetForSelector(_:) will never get called. @Nathan Perry 的解决方案接近了,但没有实现respondsToSelector(_:) ,向委托发送消息的 UIKit 代码将认为没有任何其他委托方法的实现,并且forwardingTargetForSelector(_:)永远不会得到叫。

So, we take control of `gestureRecognizer(_:, shouldReceiveTouch:) in the one specific scenario we want to modify the behavior, and otherwise forward everything else to the delegate.因此,我们在想要修改行为的一个特定场景中控制 `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
        }
    }
}

You can subclass UINavigationController as following:您可以将 UINavigationController 子类化如下:

@interface CustomNavigationController : UINavigationController<UIGestureRecognizerDelegate>

@end

Implementation:执行:

@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

Simple, no side-effect Answer简单,无副作用

While most answers here are good, they seemingly have unintended side-effects (app breaking) or are verbose.虽然这里的大多数答案都很好,但它们似乎有意想不到的副作用(应用程序中断)或冗长。

The most simple yet functional solution I could come up with was the following:我能想到的最简单但最实用的解决方案如下:

In the ViewController that you are hiding the navigationBar,在隐藏导航栏的 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
    }
}

Other answers have suggested merely setting the delegate to nil.其他答案建议仅将委托设置为零。 Swiping backwards to the initial view controller on the navigation stack results in all gestures to be disabled.向后滑动到导航堆栈上的初始视图控制器会导致禁用所有手势。 Some sort of oversight, perhaps, of the UIKit/UIGesture devs.也许是对 UIKit/UIGesture 开发者的某种疏忽。

As well, some answers here that I have implemented resulted in non-standard apple navigation behaviour (specifically, allowing for the ability to scroll up or down while also swiping backwards).同样,我在这里实现的一些答案导致了非标准的苹果导航行为(特别是允许向上或向下滚动同时也向后滑动的能力)。 These answers also seem a bit verbose and in some cases incomplete.这些答案似乎也有点冗长,在某些情况下是不完整的。

Building off of Hunter Maximillion Monk's answer , I made a subclass for UINavigationController and then set the custom class for my UINavigationController in my storyboard.基于Hunter Maximillion Monk 的回答,我为 UINavigationController 创建了一个子类,然后在我的故事板中为我的 UINavigationController 设置了自定义类。 Final code for the two classes looks like this:这两个类的最终代码如下所示:

InteractivePopRecognizer: 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: 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)
    }
}

Storyboard:故事板:

故事板导航控制器自定义类

Looks like solution provided by @ChrisVasseli is the best.看起来@ChrisVasseli 提供的解决方案是最好的。 I'd like to provide same solution in Objective-C because question is about Objective-C (see tags)我想在 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

My solution is to directly extend the UINavigationController class :我的解决方案是直接扩展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
    }

}

This way, all navigation controllers will be dismissable by sliding.这样,所有导航控制器都可以通过滑动关闭。

The answer of Hunter Monk is really awesome, but unfortunately in iOS 13.3.1, it does not work. Hunter Monk 的回答真的很牛逼,可惜在 iOS 13.3.1 中就不行了。

I will explain another way to hide UINavigationBar and not lose swipe to back gesture .我将解释另一种隐藏UINavigationBar并且不会丢失swipe to back gesture的方法。 I have tested on iOS 13.3.1 and 12.4.3 and it works.我已经在 iOS 13.3.1 和 12.4.3 上进行了测试,并且可以正常工作。

You need to create a custom class of UINavigationController and set that class for UINavigationController in Storyboard您需要创建一个UINavigationController的自定义类并在Storyboard中为UINavigationController设置该类

将自定义类设置为 <code>UINavigationController</code>

Do NOT hide the NavigationBar on the Storyboard不要隐藏Storyboard上的NavigationBar

<code>UINavigationController</code> 属性检查器:

Example on Storyboard : Storyboard的例子:

故事板:

And finally, put this: navigationBar.isHidden = true in viewDidLoad of CustomNavigationController class.最后,把这个: navigationBar.isHidden = true放在CustomNavigationController类的viewDidLoad中。

Make sure, do NOT use this method setNavigationBarHidden(true, animated: true) for hiding the NavigationBar .确保不要使用此方法setNavigationBarHidden(true, animated: true)来隐藏NavigationBar

import UIKit

class CustomNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationBar.isHidden = true
    }
}

You can do it with a Proxy Delegate.您可以使用代理委托来完成。 When you are building the navigation controller, grab the existing delegate.在构建导航控制器时,获取现有的委托。 And pass it into the proxy.并将其传递给代理。 Then pass all delegate methods to the existing delegate except gestureRecognizer:shouldReceiveTouch: using forwardingTargetForSelector:然后将所有委托方法传递给现有委托,除了gestureRecognizer:shouldReceiveTouch:使用forwardingTargetForSelector:

Setup:设置:

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

Proxy Delegate:代理委托:

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
    }  
}

Here is my solution: I am changing alpha on the navigation bar, but the navigation bar is not hidden.这是我的解决方案:我正在更改导航栏上的 alpha,但导航栏没有隐藏。 All my view controllers are a subclass of my BaseViewController, and there I have:我所有的视图控制器都是我的 BaseViewController 的子类,我有:

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

You could also subclass UINavigationController and put that method there.您还可以继承 UINavigationController 并将该方法放在那里。

TLDR- Solution without any side effects: TLDR-没有任何副作用的解决方案:

Instead of creating UINavigationController from storyboard, create a custom class inheriting UINavigationController and present it via code.与其从故事板创建 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
}

Other solutions tried:尝试过的其他解决方案:

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

  2. Setting interactivePopGestureRecognizer.delegate = self and then doing this in viewDidAppear or at some other place.设置 interactivePopGestureRecognizer.delegate = self 然后在 viewDidAppear 或其他地方执行此操作。

    if navigationController?.viewControllers.count ??如果navigationController?.viewControllers.count ?? 0 > 1 { navigationController?.interactivePopGestureRecognizer?.isEnabled = true } else { navigationController?.interactivePopGestureRecognizer?.isEnabled = false } 0 > 1 { navigationController?.interactivePopGestureRecognizer?.isEnabled = true } 否则 { navigationController?.interactivePopGestureRecognizer?.isEnabled = false }

This worked fine as long as there were more than 1 viewControllers in the stack.只要堆栈中有 1 个以上的视图控制器,它就可以正常工作。 App freezes if the count is <= 1.如果计数 <= 1,应用程序将冻结。

Xamarin Answer: Xamarin 答案:

Implement the IUIGestureRecognizerDelegate Interface in your ViewController's Class definition:在 ViewController 的类定义中实现IUIGestureRecognizerDelegate接口:

public partial class myViewController : UIViewController, IUIGestureRecognizerDelegate

In your ViewController add the following method:在您的 ViewController 中添加以下方法:

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

In your ViewController's ViewDidLoad() add the following line :在您的 ViewController 的ViewDidLoad()中添加以下行:

NavigationController.InteractivePopGestureRecognizer.Delegate = this;

I've tried this and it's working perfectly : How to hide Navigation Bar without losing slide-back ability我已经尝试过了,它工作得很好: 如何隐藏导航栏而不失去滑回能力

The idea is to implement "UIGestureRecognizerDelegate" in your .h and add this to your .m file.这个想法是在您的.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;  
}

有些人通过使用动画YES调用setNavigationBarHidden方法取得了成功。

In my view controller without navigationbar I use在我没有导航栏的视图控制器中,我使用

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()
}

During the interactive dismissal the back button will shine through though, which is why I hid it.在交互式解雇期间,后退按钮会发光,这就是我隐藏它的原因。

There is a really simple solution that I tried and works perfectly, this is in Xamarin.iOS but can be applied to native too:有一个非常简单的解决方案,我尝试过并且效果很好,它在 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);
    }

Here is how to disable de gesture recognizer when user slides out of the ViewController.以下是当用户滑出 ViewController 时如何禁用手势识别器。 You can paste it on your viewWillAppear() or on your ViewDidLoad() methods.您可以将其粘贴到 viewWillAppear() 或 ViewDidLoad() 方法上。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM