it-swarm.com.de

Versuch, die "Zurück" -Navigationstastenaktion in iOS auszuführen

Ich muss feststellen, wenn der Benutzer auf die Schaltfläche "Zurück" in der Navigationsleiste tippt, um einige Vorgänge auszuführen, wenn dies der Fall ist. Ich versuche, eine Aktion auf eine solche Schaltfläche manuell zu setzen:

[self.navigationItem.backBarButtonItem setAction:@selector(performBackNavigation:)];

- (void)performBackNavigation:(id)sender
{
   // Do operations

   [self.navigationController popViewControllerAnimated:NO];
}

Zuerst habe ich diesen Code in den View-Controller selbst eingefügt, aber ich fand heraus, dass self.navigationItem.backBarButtonItem scheinbar nil war. Daher habe ich denselben Code in den übergeordneten View-Controller verschoben, der den ersteren in den Navigationsstapel schiebt. Aber ich kann es auch nicht schaffen. Ich habe einige Beiträge zu diesem Problem gelesen, und einige von ihnen sagten, dass der Selektor am übergeordneten View-Controller festgelegt werden muss, aber für mich funktioniert das sowieso nicht ... Was kann ich falsch machen?

Vielen Dank

67
AppsDev

Versuchen Sie diesen Code mit der VIewWillDisappear-Methode, um das Drücken der Zurück-Taste von NavigationItem zu erkennen:

-(void) viewWillDisappear:(BOOL)animated
{
    if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) 
    {
        // Navigation button was pressed. Do some stuff 
        [self.navigationController popViewControllerAnimated:NO];
    }
    [super viewWillDisappear:animated];
}

ODER Es gibt eine andere Möglichkeit, die Aktion mit der Schaltfläche Navigation BAck zu aktivieren.

Benutzerdefinierte Schaltfläche für UINavigationItem der Schaltfläche "Zurück" erstellen.

Für Ex: 

In ViewDidLoad:

- (void)viewDidLoad 
{
    [super viewDidLoad];
    UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle:@"Home" style:UIBarButtonItemStyleBordered target:self action:@selector(home:)];
    self.navigationItem.leftBarButtonItem=newBackButton;
}

-(void)home:(UIBarButtonItem *)sender 
{
    [self.navigationController popToRootViewControllerAnimated:YES];
}

Swift:

override func willMoveToParentViewController(parent: UIViewController?) 
{
    if parent == nil 
    {
        // Back btn Event handler
    }
}
126
Kumar KL

Schnell

override func didMoveToParentViewController(parent: UIViewController?) {
    if parent == nil {
        //"Back pressed"
    }
}
40
dadachi

Vielleicht passt diese Antwort nicht zu Ihrer Erklärung, sondern zum Fragetitel. Dies ist nützlich, wenn Sie wissen möchten, wann Sie die Zurück-Schaltfläche einer UINavigationBar-Taste gedrückt haben.

In diesem Fall können Sie das UINavigationBarDelegate-Protokoll verwenden und eine dieser Methoden implementieren:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;
- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;

Wenn die didPopItem-Methode aufgerufen wird, ist dies darauf zurückzuführen, dass Sie entweder auf die Zurück-Schaltfläche geklickt haben oder die [UINavigationBar popNavigationItemAnimated:]-Methode verwendet haben und die Navigationsleiste das Element geöffnet hat.

Wenn Sie nun wissen möchten, welche Aktion die didPopItem-Methode ausgelöst hat, können Sie ein Flag verwenden.

Bei diesem Ansatz muss ich nicht manuell ein linkes Balkenschaltflächenelement mit einem Pfeilbild hinzufügen, um es der iOS-Zurückschaltfläche ähnlich zu machen und in der Lage zu sein, mein benutzerdefiniertes Ziel/meine benutzerdefinierte Aktion festzulegen.


Sehen wir uns ein Beispiel an:

Ich habe einen Ansichtscontroller mit einem Seitensichtcontroller und einer benutzerdefinierten Seitenindikatoransicht. Ich verwende auch eine benutzerdefinierte UINavigationBar, um einen Titel anzuzeigen, auf der ich bin, und die Zurück-Taste, um zur vorherigen Seite zurückzukehren. Ich kann auch zur vorherigen/nächsten Seite auf dem Seitencontroller streichen.

#pragma mark - UIPageViewController Delegate Methods
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {

    if( completed ) {

        //...

        if( currentIndex > lastIndex ) {

            UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:@"Some page title"];

            [[_someViewController navigationBar] pushNavigationItem:navigationItem animated:YES];
            [[_someViewController pageControl] setCurrentPage:currentIndex];
        } else {
            _autoPop = YES; //We pop the item automatically from code.
            [[_someViewController navigationBar] popNavigationItemAnimated:YES];
            [[_someViewController pageControl] setCurrentPage:currentIndex];
        }
    }

}

Dann implementiere ich UINavigationBar-Delegatmethoden:

#pragma mark - UINavigationBar Delegate Methods
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
    if( !_autoPop ) {
        //Pop by back button tap
    } else {
        //Pop from code
    }

    _autoPop = NO;

    return YES;
}

In diesem Fall habe ich shouldPopItem verwendet, da der Pop animiert ist und ich die Schaltfläche "Zurück" sofort behandeln und nicht warten möchte, bis der Übergang abgeschlossen ist.

16
Firula

Das Problem mit didMoveToParentViewController ist, dass es aufgerufen wird, sobald die übergeordnete Ansicht wieder vollständig sichtbar ist. Wenn Sie also zuvor einige Aufgaben ausführen müssen, funktioniert sie nicht.

Und es funktioniert nicht mit der gesteuerten Animationsgeste Die Verwendung von willMoveToParentViewController funktioniert besser.

Ziel c

- (void)willMoveToParentViewController:(UIViewController *)parent{
    if (parent == NULL) {
        // ...
    }
}

Swift

override func willMoveToParentViewController(parent: UIViewController?) {
    if parent == nil {
        // ...  
    }
}
12
Nico

Dies ist die Objective-C-Version von dadachis Answer:

Ziel c

- (void)didMoveToParentViewController:(UIViewController *)parent{
    if (parent == NULL) {
        NSLog(@"Back Pressed");
    }
}
6
Ashish Kakkad

Legen Sie den Delegierten der UINavigationBar fest und verwenden Sie dann:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
    //handle the action here
}
2
Jeffrey Sun

Keine der anderen Lösungen hat für mich funktioniert, aber dies funktioniert:

Erstellen Sie Ihre eigene Unterklasse von UINavigationController, lassen Sie UINavigationBarDelegate implementieren (der Delegat der Navigationsleiste muss nicht manuell festgelegt werden), fügen Sie eine UIViewController-Erweiterung hinzu, die eine Methode definiert, die bei einem Zurück-Tastendruck aufgerufen werden soll, und implementieren Sie diese Methode anschließend in Ihrer UINavigationController-Unterklasse :

func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
    self.topViewController?.methodToBeCalledOnBackButtonPress()
    self.popViewController(animated: true)
    return true
}
1
Shady

Legen Sie die UINavigationControllerDelegate fest und implementieren Sie diese Delegatenfunktion (Swift):

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
    if viewController is <target class> {
        //if the only way to get back - back button was pressed
    }
}
1
mark

Verwenden Sie eine benutzerdefinierte UINavigationController-Unterklasse, die die shouldPop-Methode implementiert. 

In Swift:

class NavigationController: UINavigationController, UINavigationBarDelegate
{
    var shouldPopHandler: (() -> Bool)?

    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool
    {
        if let shouldPopHandler = self.shouldPopHandler, !shouldPopHandler()
        {
            return false
        }
        self.popViewController(animated: true) // Needed!
        return true
    }
}

Wenn festgelegt, wird Ihre shouldPopHandler() aufgerufen, um zu entscheiden, ob der Controller Pop ist oder nicht. Wenn nicht gesetzt, wird es wie gewohnt gepoppt.

Es ist eine gute Idee, UINavigationControllers interactivePopGestureRecognizer zu deaktivieren, da die Geste Ihren Handler sonst nicht aufrufen würde.

0
Rivera

In Swift 4 oder höher:

override func didMove(toParent parent: UIViewController?) {
    if parent == nil {
        //"Back pressed"
    }
}
0
iMichele