Ich liebe das Swipe Pack, das durch das Einbetten Ihrer Ansichten in a geerbt wurde UINavigationController
. Leider kann ich keinen Weg finden, das zu verbergen, NavigationBar
aber ich habe immer noch die Touch-Pan-Wischfunktion zurück gesture
. Ich kann benutzerdefinierte Gesten schreiben, aber ich ziehe es vor, mich stattdessen nicht auf das UINavigationController
Zurückwischen gesture
zu verlassen.
Wenn ich es im Storyboard deaktiviere, funktioniert das Zurückwischen nicht
alternativ, wenn ich es programmgesteuert verstecke, das gleiche Szenario.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES animated:NO]; // and animated:YES
}
Gibt es keine Möglichkeit, das Oberteil zu verstecken NavigationBar
und trotzdem zu wischen?
Antworten:
Ein Hack, der funktioniert, besteht darin, den
interactivePopGestureRecognizer
Delegierten des zu setzen , um FolgendesUINavigationController
zunil
mögen:In einigen Situationen kann es jedoch zu seltsamen Effekten kommen.
quelle
gestureRecognizerShouldBegin
, die Rückkehr ,true
wenn dienavigationController
‚sviewController
Zahl größer als 0viewWillDisappear
Bisher sind keine nachteiligen Nebenwirkungen aufgetreten.Probleme mit anderen Methoden
Das Einstellen von
interactivePopGestureRecognizer.delegate = nil
hat unbeabsichtigte Nebenwirkungen.Die Einstellung
navigationController?.navigationBar.hidden = true
funktioniert, lässt jedoch nicht zu, dass Ihre Änderung in der Navigationsleiste ausgeblendet wird.Schließlich ist es im Allgemeinen besser, ein Modellobjekt zu erstellen, das
UIGestureRecognizerDelegate
für Ihren Navigationscontroller geeignet ist. Das Festlegen auf einen Controller imUINavigationController
Stapel verursacht dieEXC_BAD_ACCESS
Fehler.Vollständige Lösung
Fügen Sie diese Klasse zunächst Ihrem Projekt hinzu:
Stellen Sie dann Ihren Navigationscontroller
interactivePopGestureRecognizer.delegate
auf eine Instanz Ihrer neuenInteractivePopRecognizer
Klasse ein.Genießen Sie eine versteckte Navigationsleiste ohne Nebenwirkungen, die auch dann funktioniert, wenn Ihr oberster Controller über Unteransichten für Tabellen-, Sammlungs- oder Bildlaufansichten verfügt.
quelle
In meinem Fall, um seltsame Effekte zu verhindern
Root View Controller
http://www.gampood.com/pop-viewcontroller-with-out-navigation-bar/
quelle
EXEC_BAD_ACCESS
UIGestureRecognizerDelegate
, dem Root-View-Controller etwas hinzuzufügen ... In meinem Fall wurde der Delegat in einem späteren View-Controller auf Null gesetzt als der Root-View-Controller. Bei der Rückkehr zum Root-View-ControllergestureRecognizerShouldBegin
wurde er also nicht aufgerufen. Also habe ich das.delegate = self
in platziertviewDidAppear()
. Das löste die seltsamen Effekte in meinem Fall. Prost!EXEC_BAD_ACCESS
dies geschieht?EXC_BAD_ACCESS
Fehler: stackoverflow.com/questions/28746123/…Aktualisiert für iOS 13.4
iOS 13.4 hat die vorherige Lösung gebrochen, daher werden die Dinge hässlich. Es sieht so aus, als würde dieses Verhalten in iOS 13.4 jetzt von einer privaten Methode gesteuert
_gestureRecognizer:shouldReceiveEvent:
(nicht zu verwechseln mit der neuen öffentlichenshouldReceive
Methode, die in iOS 13.4 hinzugefügt wurde).Ich stellte fest, dass andere veröffentlichte Lösungen, die den Delegaten überschrieben oder auf Null setzten, ein unerwartetes Verhalten verursachten.
In meinem Fall schlug es (wie erwartet) fehl, wenn ich mich oben auf dem Navigationsstapel befand und versuchte, mit der Geste eine weitere zu öffnen, aber nachfolgende Versuche, auf den Stapel zu drücken, verursachten seltsame grafische Störungen im Navigationsleiste. Dies ist sinnvoll, da der Delegat nicht nur verwendet wird, um zu verhindern, dass die Geste erkannt wird, wenn die Navigationsleiste ausgeblendet ist, und das gesamte andere Verhalten verworfen wird.
Aus meinen Tests geht hervor, dass dies
gestureRecognizer(_:, shouldReceiveTouch:)
die Methode ist, die der ursprüngliche Delegat implementiert, um zu verhindern, dass die Geste erkannt wird, wenn die Navigationsleiste ausgeblendet ist, nichtgestureRecognizerShouldBegin(_:)
. Andere Lösungen, diegestureRecognizerShouldBegin(_:)
in ihrer Delegiertenarbeit implementiertgestureRecognizer(_:, shouldReceiveTouch:)
werden, weil das Fehlen einer Implementierung von das Standardverhalten beim Empfangen aller Berührungen verursacht.Die Lösung von @Nathan Perry kommt nahe, aber ohne eine Implementierung von
respondsToSelector(_:)
wird der UIKit-Code, der Nachrichten an den Delegierten sendet, glauben, dass es keine Implementierung für eine der anderen Delegatenmethoden gibt, undforwardingTargetForSelector(_:)
wird niemals aufgerufen.Wir übernehmen also die Kontrolle über `gestureRecognizer (_:, shouldReceiveTouch :) in dem einen bestimmten Szenario, in dem wir das Verhalten ändern möchten, und leiten ansonsten alles andere an den Delegaten weiter.
quelle
gestureRecognizerShouldBegin:
Ding gemacht, und es "scheint zu funktionieren". Ich frage mich, worauf ich achten sollte.navigationController
eine starke Referenz im AlwaysPoppableDelegate war. Ich habe den Code bearbeitet, um dies alsweak
Referenz zu verwenden.Sie können UINavigationController wie folgt unterordnen:
Implementierung:
quelle
UIPageViewController
Overscroll unterbrochen.Einfache Antwort ohne Nebenwirkungen
Während die meisten Antworten hier gut sind, haben sie scheinbar unbeabsichtigte Nebenwirkungen (App Breaking) oder sind ausführlich.
Die einfachste und zugleich funktionellste Lösung, die ich finden konnte, war die folgende:
In dem ViewController, in dem Sie die Navigationsleiste verstecken,
Andere Antworten haben vorgeschlagen, den Delegierten lediglich auf Null zu setzen. Wenn Sie rückwärts zum ursprünglichen Ansichts-Controller auf dem Navigationsstapel wischen, werden alle Gesten deaktiviert. Vielleicht eine Art Versehen der UIKit / UIGesture-Entwickler.
Außerdem haben einige Antworten, die ich hier implementiert habe, zu einem nicht standardmäßigen Apple-Navigationsverhalten geführt (insbesondere die Möglichkeit, nach oben oder unten zu scrollen und gleichzeitig rückwärts zu wischen). Diese Antworten wirken auch etwas ausführlich und in einigen Fällen unvollständig.
quelle
viewDidLoad()
ist kein guter Ort zum Erfassen,initialInteractivePopGestureRecognizerDelegate
danavigationController
es dort null sein könnte (noch nicht auf den Stapel geschoben).viewWillAppear
Der Ort, an dem Sie die Navigationsleiste verstecken, ist besser geeignetAufbauend auf der Antwort von Hunter Maximillion Monk ich eine Unterklasse für UINavigationController erstellt und dann die benutzerdefinierte Klasse für meinen UINavigationController in meinem Storyboard festgelegt. Der endgültige Code für die beiden Klassen sieht folgendermaßen aus:
InteractivePopRecognizer:
HiddenNavBarNavigationController:
Storyboard:
quelle
Die von @ChrisVasseli bereitgestellte Lösung scheint die beste zu sein. Ich möchte dieselbe Lösung in Objective-C bereitstellen, da es sich bei der Frage um Objective-C handelt (siehe Tags).
quelle
Meine Lösung besteht darin, die
UINavigationController
Klasse direkt zu erweitern :Auf diese Weise können alle Navigationssteuerungen durch Schieben geschlossen werden.
quelle
viewDidAppear
Aufrufe der VCs eines Navigationscontrollers ignoriert.Sie können dies mit einem Proxy-Delegaten tun. Wenn Sie den Navigationscontroller erstellen, greifen Sie auf den vorhandenen Delegaten zu. Und geben Sie es an den Proxy weiter. Übergeben Sie dann alle Delegatmethoden an den vorhandenen Delegaten, außer
gestureRecognizer:shouldReceiveTouch:
mitforwardingTargetForSelector:
Konfiguration:
Proxy-Delegierter:
quelle
Die Antwort von Hunter Monk ist wirklich großartig, aber leider funktioniert es in iOS 13.3.1 nicht.
Ich werde einen anderen Weg erklären, sich zu verstecken
UINavigationBar
und nicht zu verlierenswipe to back gesture
. Ich habe auf iOS 13.3.1 und 12.4.3 getestet und es funktioniert.Sie müssen eine benutzerdefinierte Klasse von in erstellen
UINavigationController
und diese Klasse fürUINavigationController
in festlegenStoryboard
Verstecke das NICHT
NavigationBar
auf demStoryboard
Beispiel zu
Storyboard
:Und zum Schluss noch:
navigationBar.isHidden = true
InviewDidLoad
derCustomNavigationController
Klasse.Stellen Sie sicher, dass Sie diese Methode NICHT
setNavigationBarHidden(true, animated: true)
zum Ausblenden der verwendenNavigationBar
.quelle
iOS 13.4.1
und Swipe Back funktioniert.Xamarin Antwort:
Implementieren Sie die
IUIGestureRecognizerDelegate
Schnittstelle in die Klassendefinition Ihres ViewControllers:Fügen Sie in Ihrem ViewController die folgende Methode hinzu:
Fügen Sie in Ihrem ViewController
ViewDidLoad()
die folgende Zeile hinzu:quelle
UINavigationController
Root View Controller? Ich bekomme das,EXEC_BAD_ACCESS
wenn ich das versuche.gestureRecognizerShouldBegin:
.Ich habe es versucht und es funktioniert perfekt: So verstecken Sie die Navigationsleiste, ohne die Fähigkeit zum Zurückschieben zu verlieren
Die Idee ist, "UIGestureRecognizerDelegate" in Ihrer .h zu implementieren und diese zu Ihrer .m-Datei hinzuzufügen.
quelle
Hier ist meine Lösung: Ich ändere Alpha in der Navigationsleiste, aber die Navigationsleiste ist nicht ausgeblendet. Alle meine View Controller sind eine Unterklasse meines BaseViewControllers, und dort habe ich:
Sie können auch UINavigationController unterordnen und diese Methode dort ablegen.
quelle
Einige Leute hatten Erfolg, indem sie die
setNavigationBarHidden
MethodeYES
stattdessen mit animierten aufgerufen haben.quelle
In meinem View Controller ohne Navigationsleiste verwende ich
Während der interaktiven Entlassung leuchtet der Zurück-Button jedoch durch, weshalb ich ihn versteckt habe.
quelle
Es gibt eine wirklich einfache Lösung, die ich ausprobiert habe und die perfekt funktioniert. Sie befindet sich in Xamarin.iOS, kann aber auch auf native angewendet werden:
quelle
Hier erfahren Sie, wie Sie die Gestenerkennung deaktivieren, wenn der Benutzer den ViewController verlässt. Sie können es in Ihre viewWillAppear () - oder in Ihre ViewDidLoad () -Methoden einfügen.
quelle