Non scorrere indietro quando si nasconde la barra di navigazione in UINavigationController


86

Adoro lo swipe pack ereditato dall'incorporamento delle tue opinioni in un file UINavigationController. Sfortunatamente non riesco a trovare un modo per nascondere il NavigationBarma ho ancora il tocco della panoramica indietro gesture. Posso scrivere gesti personalizzati ma preferisco non farlo e fare affidamento sullo UINavigationControllerswipe all'indietrogesture invece.

se lo deseleziono nello storyboard, il passaggio all'indietro non funziona

inserisci qui la descrizione dell'immagine

in alternativa, se lo nascondo a livello di codice, lo stesso scenario.

Non c'è modo di nascondere la parte superiore NavigationBare mantenere lo swipe?


1
L'aggiunta di un UIGestureRecognizer è accettabile? È un gioco da ragazzi da implementare.
SwiftArchitect

1
@LancelotdelaMare, stavo cercando di evitarlo poiché non funzionerà in modo fluido come lo scorrimento indietro di UINavigationController. Sto esaminando UIScreenEdgePanGestureRecognizer poiché alcune persone dicono che aiuta ma non è ancora riuscito a farlo funzionare. Alla ricerca della soluzione più semplice ed elegante qui.
mihai

Risposte:


98

Un trucco che sta funzionando è impostare il interactivePopGestureRecognizerdelegato di di UINavigationControllerin nilquesto modo:

[self.navigationController.interactivePopGestureRecognizer setDelegate:nil];

Ma in alcune situazioni potrebbe creare strani effetti.


16
"scorrere ripetutamente indietro può far riconoscere il gesto quando c'è un solo controller di visualizzazione sullo stack, il che a sua volta mette un'interfaccia utente in uno stato (penso inaspettato dagli ingegneri UIKit) in cui smette di riconoscere i gesti"
HorseT

4
Un'alternativa che potrebbe proteggere da quello stato imprevisto sarebbe quella di impostarlo su un oggetto di basso livello (ho usato il mio delegato dell'app) e implementarlo gestureRecognizerShouldBegin, restituendo truese il conteggio di navigationControllers viewControllerè maggiore di 0.
Kenny Winker

4
Sebbene funzioni, lo consiglio vivamente di non farlo. L'interruzione del delegato causava un blocco del thread principale raro e difficile da identificare. Si scopre che non è un blocco del thread principale ma è quello descritto da @HorseT.
Josh Bernfeld

3
La mia app salva l'handle del delegato, quindi lo ripristina viewWillDisappeare finora non hanno avuto effetti collaterali negativi.
Don Park

1
!!!! Sconsiglio vivamente di utilizzare questa soluzione, quando si utilizza ripetutamente lo scorrimento si verifica uno strano comportamento, il retro è disabilitato e l'intera app non risponde più
KarimIhab

81

Problemi con altri metodi

L'impostazione di interactivePopGestureRecognizer.delegate = nilha effetti collaterali indesiderati.

L'impostazione navigationController?.navigationBar.hidden = truefunziona, ma non consente di nascondere la modifica nella barra di navigazione.

Infine, è generalmente migliore pratica creare un oggetto modello che sia il UIGestureRecognizerDelegatecontroller di navigazione. L'impostazione su un controller nello UINavigationControllerstack è ciò che causa gli EXC_BAD_ACCESSerrori.

Soluzione completa

Innanzitutto, aggiungi questa classe al tuo progetto:

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

Quindi, imposta il controller di navigazione interactivePopGestureRecognizer.delegatesu un'istanza della tua nuova InteractivePopRecognizerclasse.

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
}

Goditi una barra di navigazione nascosta senza effetti collaterali, che funziona anche se il tuo controller superiore ha viste secondarie di visualizzazione tabella, raccolta o scorrimento.


2
Ottima soluzione!
Matt Butler

2
La migliore risposta, grazie!
Dory Daniel,

3
@HunterMaximillionMonk grazie per l'ottima soluzione. Funziona a meraviglia
come diu

2
Sicuramente la migliore risposta!
daxh

2
Ha funzionato su iOS 13.5, 12.4.6 e 10.3.4. Grazie.
Денис Попов

55

Nel mio caso, per evitare strani effetti

Controller di visualizzazione radice

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
}

2
A volte ottengo EXC_BAD_ACCESS quando lo uso
Andrey Gordeev

Per me, non fa funzionare il gesto e spesso si blocca conEXEC_BAD_ACCESS
Benjohn

2
Ricordarsi di aggiungere UIGestureRecognizerDelegateal controller di visualizzazione root ... Nel mio caso il delegato era impostato su nil in un controller di visualizzazione successivo rispetto al controller di visualizzazione root, quindi quando restituito al controller di visualizzazione root, gestureRecognizerShouldBeginnon è stato chiamato. Quindi ho inserito il file .delegate = selfin viewDidAppear(). Questo ha risolto gli strani effetti nel mio caso .. Saluti!
Wiingaard

@AndreyGordeev Potresti fornire alcuni dettagli su quando EXEC_BAD_ACCESSaccade?
Jaybo

Ecco ulteriori informazioni EXC_BAD_ACCESSsull'errore: stackoverflow.com/questions/28746123/…
Andrey Gordeev

25

Aggiornato per iOS 13.4

iOS 13.4 ha rotto la soluzione precedente, quindi le cose si metteranno male. Sembra che in iOS 13.4 questo comportamento sia ora controllato da un metodo privato _gestureRecognizer:shouldReceiveEvent:(da non confondere con il nuovo shouldReceivemetodo pubblico aggiunto in iOS 13.4).


Ho scoperto che altre soluzioni pubblicate che sovrascrivono il delegato o impostarlo su zero hanno causato un comportamento imprevisto.

Nel mio caso, quando ero in cima allo stack di navigazione e ho provato a utilizzare il gesto per visualizzarne un altro, non sarebbe riuscito (come previsto), ma i successivi tentativi di inserire nello stack avrebbero iniziato a causare strani problemi grafici nel barra di navigazione. Questo ha senso, perché il delegato viene utilizzato per gestire qualcosa di più che bloccare o meno il riconoscimento del gesto quando la barra di navigazione è nascosta e tutto l'altro comportamento è stato eliminato.

Dai miei test, sembra che gestureRecognizer(_:, shouldReceiveTouch:)sia il metodo che il delegato originale sta implementando per bloccare il riconoscimento del gesto quando la barra di navigazione è nascosta, non gestureRecognizerShouldBegin(_:). Altre soluzioni che implementano gestureRecognizerShouldBegin(_:)nel loro lavoro delegato a causa della mancanza di un'implementazione digestureRecognizer(_:, shouldReceiveTouch:) causerà il comportamento predefinito di ricevere tutti i tocchi.

La soluzione di @Nathan Perry si avvicina, ma senza un'implementazione di respondsToSelector(_:), il codice UIKit che invia messaggi al delegato crederà che non vi sia alcuna implementazione per nessuno degli altri metodi delegato e forwardingTargetForSelector(_:)non verrà mai chiamato.

Quindi, prendiamo il controllo di `gestureRecognizer (_ :, shouldReceiveTouch :) nello scenario specifico in cui vogliamo modificare il comportamento, e altrimenti inoltriamo tutto il resto al delegato.

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

1
Sembra che la tua soluzione sia la migliore per questo momento. Grazie!
Timur Bernikovich

"ma i successivi tentativi di inserire nello stack comincerebbero a causare strani problemi grafici nella barra di navigazione" - Sono confuso qui. Pensavo non avessimo la barra di navigazione? Questa è la domanda? Nella mia situazione, ho un controller di navigazione incorporato come controller di visualizzazione figlio senza barra di navigazione; il VC contenitore ha i controlli di navigazione. Quindi ho lasciato che il VC contenitore fosse il delegato del riconoscitore e ho fatto la gestureRecognizerShouldBegin:cosa, e "sembra funzionare". Chiedendomi dovrei stare attento.
skagedal

2
Si è verificata una perdita di memoria poiché navigationControllerera un riferimento forte in AlwaysPoppableDelegate. Ho modificato il codice per renderlo un weakriferimento.
Graham Perks

3
Questa bella soluzione non funziona più in iOS 13.4
Ely

@ChrisVasselli Davvero fantastico, grazie! Si spera che questo superi il controllo dei metodi privati ​​della revisione dell'App Store.
Ely

16

Puoi sottoclassare UINavigationController come segue:

@interface CustomNavigationController : UINavigationController<UIGestureRecognizerDelegate>

@end

Implementazione:

@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

2
Usare questo approccio sta interrompendo il gesto pop in UIPageViewControlleroverscroll.
atulkhatri

Ho scoperto che viewController.count> 1 controllo è necessario. Se l'utente tenta di scorrere indietro solo con il VC radice, l'interfaccia utente si bloccherà al successivo push VC.
VaporwareWolf

12

Risposta semplice, senza effetti collaterali

Sebbene la maggior parte delle risposte qui siano buone, apparentemente hanno effetti collaterali non intenzionali (interruzione dell'app) o sono prolisse.

La soluzione più semplice ma funzionale che sono riuscito a trovare è stata la seguente:

Nel ViewController in cui stai nascondendo la navigationBar,

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

Altre risposte hanno suggerito semplicemente di impostare il delegato a zero. Scorrendo all'indietro fino al controller di visualizzazione iniziale nello stack di navigazione, tutti i gesti verranno disabilitati. Una sorta di svista, forse, degli sviluppatori di UIKit / UIGesture.

Inoltre, alcune risposte qui che ho implementato hanno portato a un comportamento di navigazione Apple non standard (in particolare, consentendo la possibilità di scorrere verso l'alto o verso il basso mentre si scorre anche all'indietro). Queste risposte sembrano anche un po 'prolisse e in alcuni casi incomplete.


viewDidLoad()non è un buon posto per catturare initialInteractivePopGestureRecognizerDelegatepoiché navigationControllerpotrebbe essere nullo lì (non ancora inserito nello stack). viewWillAppeardel luogo in cui stai nascondendo la barra di navigazione sarebbe più appropriato
nCod3d

10

Partendo dalla risposta di Hunter Maximillion Monk , ho creato una sottoclasse per UINavigationController e quindi ho impostato la classe personalizzata per il mio UINavigationController nel mio storyboard. Il codice finale per le due classi è simile a questo:

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

Storyboard:

Classe personalizzata del controller di navigazione dello storyboard


8

Sembra che la soluzione fornita da @ChrisVasseli sia la migliore. Vorrei fornire la stessa soluzione in Objective-C perché la domanda riguarda Objective-C (vedi tag)

@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

3
Perché ObjC non è ancora morto! 😉
MonsieurDart

2
Questa è la soluzione corretta. Qualsiasi altra soluzione che non inoltra al delegato originale non è corretta.
Josh Bernfeld

6

La mia soluzione è estendere direttamente la UINavigationControllerclasse:

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
    }

}

In questo modo, tutti i controller di navigazione saranno ignorabili facendo scorrere.


Stranamente, questo fa sì che tutte le viewDidAppearchiamate sui VC appartenenti a qualsiasi controller di navigazione vengano ignorate.
cumanzor

4

Puoi farlo con un delegato proxy. Quando crei il controller di navigazione, prendi il delegato esistente. E passalo al proxy. Quindi passare tutti i metodi delegato al delegato esistente trannegestureRecognizer:shouldReceiveTouch: usingforwardingTargetForSelector:

Impostare:

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

Delegato proxy:

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

Questa risposta è il vero stile Obj-C!
Sound Blaster

forwardingTargetForSelector mi avrebbe risparmiato così tanto tempo su un progetto passato se l'avessi saputo. Roba buona!
VaporwareWolf

4

La risposta di Hunter Monk è davvero fantastica, ma sfortunatamente in iOS 13.3.1 non funziona.

Spiegherò un altro modo per nascondersi UINavigationBare non perdere swipe to back gesture. Ho provato su iOS 13.3.1 e 12.4.3 e funziona.

È necessario creare una classe personalizzata UINavigationControllere impostarla per UINavigationControllerinStoryboard

Imposta la classe personalizzata su <code> UINavigationController </code>

NON nascondere NavigationBaril fileStoryboard

<code> UINavigationController </code> Ispettore attributi:

Esempio su Storyboard:

Storyboard:

E infine, metti questo: navigationBar.isHidden = truein viewDidLoadof CustomNavigationControllerclass.

Assicurati di NON utilizzare questo metodo setNavigationBarHidden(true, animated: true)per nascondere il file NavigationBar.

import UIKit

class CustomNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationBar.isHidden = true
    }
}

2
L'ho testato su un dispositivo reale iPhone 6S Plus iOS 13.4.1e lo scorrimento indietro funziona.
Emre Aydin

1

Risposta Xamarin:

Implementa l' IUIGestureRecognizerDelegateinterfaccia nella definizione della classe del tuo ViewController:

public partial class myViewController : UIViewController, IUIGestureRecognizerDelegate

Nel tuo ViewController aggiungi il seguente metodo:

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

Nel tuo ViewController ViewDidLoad()aggiungi la seguente riga:

NavigationController.InteractivePopGestureRecognizer.Delegate = this;

Presumibilmente questo è nel UINavigationControllercontroller di visualizzazione principale di? Ottengo il EXEC_BAD_ACCESSquando provo questo.
Benjohn

Sei in grado di eseguire la panoramica dei bordi sul controller della vista principale? Ciò non dovrebbe essere possibile perché quando sei alla radice VC hai fatto scoppiare tutti gli altri VC e la lunghezza dell'array VC del tuo Nav dovrebbe essere 1.
Ahmad

Il crash si verifica prima della chiamata a gestureRecognizerShouldBegin:.
Benjohn

1
È possibile pubblicare il codice VC in una nuova domanda o nei forum Xamarin?
Ahmad

No, non l'ho fatto. Penso che lo lascerò per .1!
Benjohn

1

L'ho provato e funziona perfettamente: come nascondere la barra di navigazione senza perdere la capacità di scorrimento indietro

L'idea è di implementare "UIGestureRecognizerDelegate" nel tuo .h e aggiungerlo al tuo file .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;  
}

1

Ecco la mia soluzione: sto cambiando alpha sulla barra di navigazione, ma la barra di navigazione non è nascosta. Tutti i miei controller di visualizzazione sono una sottoclasse del mio BaseViewController, e lì ho:

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

Puoi anche sottoclassare UINavigationController e inserire quel metodo lì.


0

Alcune persone hanno avuto successo chiamando il setNavigationBarHiddenmetodo con animato YESinvece.


Non ho provato fortuna. Aggiornamento della mia risposta per coprire questo suggerimento.
mihai

0

Nel mio controller di visualizzazione senza barra di navigazione che utilizzo

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

Durante il licenziamento interattivo, il pulsante Indietro brillerà però, motivo per cui l'ho nascosto.


-2

C'è una soluzione davvero semplice che ho provato e funziona perfettamente, questa è in Xamarin.iOS ma può essere applicata anche al nativo:

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

-6

Ecco come disabilitare il riconoscimento dei gesti quando l'utente esce dal ViewController. Puoi incollarlo sul tuo viewWillAppear () o sui tuoi metodi ViewDidLoad ().

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

Si prega di leggere la domanda prima di pubblicare le risposte. La domanda era abilitarlo, non disabilitarlo. AMIAMO IL GESTO POP.
Yogesh Maheshwari
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.