Domanda

Devo sapere quando il mio controller di visualizzazione sta per essere espulso da uno stack di navigazione in modo da poter eseguire un'azione.

Non riesco a usare -viewWillDisappear, perché viene chiamato quando il controller di visualizzazione viene spostato dallo schermo per QUALSIASI motivo (come un nuovo controller di visualizzazione che viene spinto in alto).

Devo specificamente sapere quando il controller sta per essere espulso da solo.

Qualsiasi idea sarebbe fantastica, grazie in anticipo.

È stato utile?

Soluzione

Non credo che ci sia un messaggio esplicito per questo, ma potresti sottoclassare UINavigationController e sovrascriverlo - popViewControllerAnimated (anche se non l'ho mai provato prima di me stesso).

In alternativa, se non ci sono altri riferimenti al controller di visualizzazione, potresti aggiungerlo al suo - dealloc?

Altri suggerimenti

Sovrascrivi il metodo viewWillDisappear nel VC presentato, quindi controlla il isMovingFromParentViewController all'interno dell'override ed esegui una logica specifica. Nel mio caso nascondo la barra degli strumenti dei controller di navigazione. Richiede ancora che il tuo VC presentato capisca che è stato spinto sebbene non sia perfetto.

Prova a sostituire willMoveToParentViewController: (anziché viewWillDisappear: ) nella sottoclasse personalizzata di UIViewController .

  

Chiamato poco prima che il controller di visualizzazione venga aggiunto o rimosso da un controller di visualizzazione contenitore.

- (void)willMoveToParentViewController:(UIViewController *)parent
{
    [super willMoveToParentViewController:parent];
    if (!parent) {
        // `self` is about to get popped.
    }
}

Fortunatamente, quando viene chiamato il metodo viewWillDisappear, viewController è già stato rimosso dallo stack, quindi sappiamo che viewController sta saltando perché non è più nel self.navigationController.viewControllers

Swift 4

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    if let nav = self.navigationController {
        let isPopping = !nav.viewControllers.contains(self)
        if isPopping {
            // popping off nav
        } else {
            // on nav, not popping off (pushing past, being presented over, etc.)
        }
    } else {
        // not on nav at all
    }
}

Codice originale

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if ((self.navigationController) && 
        (![self.navigationController.viewControllers containsObject:self])) {
        NSLog(@"I've been popped!");
    }
}

Questo funziona per me.

- (void)viewDidDisappear:(BOOL)animated
{
    if (self.parentViewController == nil) {
        NSLog(@"viewDidDisappear doesn't have parent so it's been popped");
        //release stuff here
    } else {
        NSLog(@"PersonViewController view just hidden");
    }
}

Puoi prenderlo qui.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {

    if (viewController == YourAboutToAppearController) {
            // do something
    }
}

Questo si attiverà poco prima della visualizzazione della nuova vista. Nessuno si è ancora mosso. Uso tutto il tempo per fare magie davanti al controllo di navigazione asinino. Puoi impostare titoli e titoli di pulsanti e fare qualunque cosa.

Ho lo stesso problema. Ho provato con viewDisDisappear, ma non ho la funzione di essere chiamata :( (non so perché, forse perché tutto il mio VC è UITableViewController). Il suggerimento di Alex funziona bene ma non riesce se il controller di navigazione viene visualizzato nella scheda Altro. In questo caso, tutti i VC dei controller di navigazione hanno il controller di navigazione come UIMoreNavigationController, non il controller di navigazione che hai sottoclassato, quindi non verrai avvisato dal navigatore quando sta per apparire un VC.
Infine, ho risolto il problema con una categoria di UINavigationController, ho appena riscritto - (UIViewController *) popViewControllerAnimated: (BOOL) animato

- (UIViewController *)popViewControllerAnimated:(BOOL)animated{
   NSLog(@"UINavigationController(Magic)");
   UIViewController *vc = self.topViewController;
   if ([vc respondsToSelector:@selector(viewControllerWillBePopped)]) {
      [vc performSelector:@selector(viewControllerWillBePopped)];
   }
   NSArray *vcs = self.viewControllers;
   UIViewController *vcc = [vcs objectAtIndex:[vcs count] - 2];
   [self popToViewController:vcc animated:YES];
   return vcc;}

Funziona bene per me: D

Ho provato questo:

- (void) viewWillDisappear:(BOOL)animated {
    // If we are disappearing because we were removed from navigation stack
    if (self.navigationController == nil) {
        // YOUR CODE HERE
    }

    [super viewWillDisappear:animated];
}

L'idea è che al momento dello scoppio, il controller di navigazione del controller di visualizzazione sia impostato su zero. Quindi, se la vista dovesse scomparire e avesse più un NavigationController, ho concluso che era saltata fuori. (potrebbe non funzionare in altri scenari).

Non posso garantire che viewWillDisappear verrà richiamato al momento del pop-up, poiché non è menzionato nei documenti. L'ho provato quando la vista era la vista dall'alto e sotto la vista dall'alto - e ha funzionato in entrambi.

Buona fortuna, Oded.

Puoi usare questo:

if(self.isMovingToParentViewController)
{
    NSLog(@"Pushed");
}
else
{
    NSLog(@"Popped");
}

Sottoclasse UINavigationController e sovrascrivi popViewController :

Swift 3

protocol CanPreventPopProtocol {
    func shouldBePopped() -> Bool
}

class MyNavigationController: UINavigationController {
    override func popViewController(animated: Bool) -> UIViewController? {
        let viewController = self.topViewController

        if let canPreventPop = viewController as? CanPreventPopProtocol {
            if !canPreventPop.shouldBePopped() {
                return nil
            }
        }
        return super.popViewController(animated: animated)
    }

    //important to prevent UI thread from freezing
    //
    //if popViewController is called by gesture recognizer and prevented by returning nil
    //UI will freeze after calling super.popViewController
    //so that, in order to solve the problem we should not return nil from popViewController
    //we interrupt the call made by gesture recognizer to popViewController through
    //returning false on gestureRecognizerShouldBegin
    //
    //tested on iOS 9.3.2 not others
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let viewController = self.topViewController

        if let canPreventPop = viewController as? CanPreventPopProtocol {
            if !canPreventPop.shouldBePopped() {
                return false
            }
        }

        return true
    }

}

Forse potresti usare la barra di navigazione di UINavigationBarDelegate: shouldPopItem protocol.

Prova a fare questo controllo in viewwilldisappear if ([self.navigationController.viewControllers indexOfObject: self] == NSNotFound) { // è scoppiato questo punto di vista. }

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top