come attivare un codice quando si ritorna dal ViewController "Over Current Content"?

nella mia app ci sono due ViewController, ViewController e ViewControler2

nel ViewController, un gruppo di pulsanti Present Modally segue to "ViewController2"

e il ViewController sovrascrive la vista

override func viewWillAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    print("will appear")
}

in ViewControler2, un pulsante per tornare indietro

@IBAction func close(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
}

ora è ancora possibile attivare viewWillAppero poi torno al ViewController da ViewController2

se cambio la presentazione di ViewControler2 da Full Screen a Over Current Context, viewWillAppear non verrà attivata

come posso attivare qualche codice quando torno?


En title : How to trigger some code when back from "Over Current Content" ViewController?

13 Comments:

  1. ci sono diversi modi per gestire questa operazione. ecco uno, che ho usato per usare.

    // ViewController1
    class ViewController1: UIViewController {
    
    
       @IBAction func presentOverCurrentContext(button: Button) {
            let vc2 = // instantiate ViewController2
            vc2.modalPresentationStyle = .overFullScreen
            vc2.presentingVC = self   // use this variable 'presentingVC' to connect both view controllers
            self.present(vc2, animated: true)
       }
    
    }
    
    
    // ViewController2
    class ViewController2: UIViewController {
    
       var presentingVC: UIViewController?  // use this variable to connect both view controllers
       @IBAction func close(button: Button) {
    
            // handle operation here
            presentingVC?.viewWillAppear(true)
    
            self.dismiss(animated: true, completion: { 
    
                // or here
                // presentingVC?.viewWillAppear(true)
            })
       }
    
    }
    

    è inoltre possibile utilizzare, il proprio metodo per ricaricare vista / viewcontroller, ma viewWillAppear è un metodo comune accessibile per tutti i controller di vista (come parte del ciclo di vita super classe) quindi potrebbe non essere necessario specificare il tipo personalizzato di controller di vista per presentingVC

  2. utilizza ViewDidDisappear / ViewWillDisappear del tuo secondo viewController per chiamare un metodo nel primo viewController. (utilizzare il protocollo / delegati per raggiungere questo obiettivo.)
  3. modo migliore / pulito per gestire questo scenario per utilizzare il gestore di richiamo.

    codice di esempio

    typealias CloseActionHandler = ()-> Void
    class TestController: UIViewController {
        var closeActionHandler: CloseActionHandler?
        func close(_ handler:@escaping CloseActionHandler) {
            self.closeActionHandler = handler
        }
        @IBAction func closeButtonTapped(_ sender: Any) {
            self.dismiss(animated: true, completion: nil)
            self.closeActionHandler?()
        }
    }
    class ViewController: UIViewController {
        func loadTestController(viewController: TestController) {
            viewController.close {
                //will be called when user will tap on close button
            }
        }
    }
    
    1. direi che un metodo migliore / più pulito sarebbe quello di implementare un protocollo e metodo delegato. dire qualcosa è il migliore è normalmente solo un'opinione.
    1. si potrebbe essere alla ricerca di articoli https://medium.cobeisfresh.com/why-you-shouldn-t-use-delegates-in-swift-7ef808a7f16b. penso che gli articoli ben spiegato perché non si dovrebbe usare delegati. detto che preferisco dirlo meglio / più pulito
    1. ho visto quell'articolo e ha alcuni punti interessanti e validi ma non è molto equilibrato. per esempio non indica gli svantaggi di usare i callback (tutto ha degli svantaggi). per esempio in un modello delegato potete generare un riferimento debole al delegato e bingo che non trattiene ma con un callback che è più duro e deve essere fatto per ogni metodo. in secondo luogo il protocollo definisce il nome della funzione e questi devono essere utilizzati quindi è chiaro nella classe adottante, ma con i richiami i nomi delle funzioni possono essere qualsiasi cosa nella classe adottante. più delegati richiedono un consiglio.
  4. si può fare senza rinunciare a segues storyboard, ma è comunque dovuto impostare volontà / ha Disappear handler in ViewCOntrolller2:

    class ViewController: UIViewController {
        ...
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let destination = segue.destination as? ViewController2 {
                (segue.destination as? ViewController2).onViewWillDisappear = {
                    //Your code
                }
            }
        }
    }
    
    class ViewController2: UIViewController {
        var onViewWillDisappear: (()->())?
    
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            onViewWillDisappear?()
        }
        ...
    }
    
    1. infine ho scelto questa versione, perché questo può mantenere le stringhe, ma sopra il codice non è un lavoro. Xcode mi suggerisce di risolvere questo problema, poi il codice è il lavoro. if segue.destination is ViewController2 {(segue.destination as! ViewController2).onViewWillDisappear = {
    1. passo successivo, Ho modificato queste due linee in ViewControler2 var onViewWillDisappear: ((_ backVal:Int)->())?, onViewWillDisappear?(1), Come leggere il valore in qui? (segue.destination as! ViewController2).onViewWillDisappear = {}
    1. @CLSo .onViewWillDisappear = { myVariable in ... } alternativamente si può usare il parametro implicito $0: .onViewWillDisappear = { print($0) }
  5. mentre le risposte finora fornite funzionano penso che sia una buona idea per mostrare come farlo utilizzando un protocollo e delegato in quanto questa è una implementazione pulita che poi permette anche per ulteriori funzionalità da aggiungere con il minimo sforzo.

    quindi impostare un protocollo come questo:

    protocol SecondViewControllerProtocol: class {
        func closed(controller: SecondViewController)
    }
    

    impostare il secondo controller di visualizzazione in questo modo:

    class SecondViewController {
        public weak var delegate: SecondViewControllerProtocol?
    
        @IBAction func close(_ sender: Any) {
            self.dismiss(animated: true, completion: nil)
            self.delegate?.close(controller: self)
        }
    }
    

    impostare il primo controller di visualizzazione in questo modo:

    class FirstViewController: SecondViewControllerProtocol {
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "SecondViewControllerID",
                let secondViewController = segue.destination as? SecondViewController {
                secondViewController.delegate = self
            }
        }
    
        func closed(controller: SecondViewController) {
        // Any code you want to execute when the second view controller is dismissed
        }
    }
    

    implementarlo in questo modo fa quello che la richiesta originale era e permette che i metodi supplementari siano messi nel protocollo in modo che il FirstViewController possa rispondere ad altre azioni nel SecondViewController.

    nota: nota:

    si potrebbe voler spostare la chiamata metodo delegato nella chiusura del gestore di esclusione in modo da sapere che il metodo non è chiamato fino a quando il SecondViewController è effettivamente andato (nel caso in cui si tenta di presentare un'altra vista che potrebbe fallire). se questo è il caso si potrebbe fare questo:

    @IBAction func close(_ sender: Any) {
        self.dismiss(animated: true) {
            self.delegate?.close(controller: self)
        }
    }
    

    in realtà si potrebbe avere una volontà e fatto metodi e li chiamano così:

    @IBAction func close(_ sender: Any) {
        self.delegate?.willClose(controller: self)
        self.dismiss(animated: true) {
            self.delegate?.didClose(controller: self)
        }
    }
    

    il che vi permetterà di fare qualcosa immediatamente, mentre il secondo controller si sta animando e poi sapere quando è effettivamente andato.

    1. dovrei inserire protocol SecondViewControllerProtocol: class { nel nuovo file swift o nel file ViewController?
    1. questo è davvero a voi e il vostro disegno, ma se non è troppo grande vorrei solo metterlo nello stesso file del controller di visualizzazione.

More similar articles:

  • come presentare il ViewController in modaly swift 4
  • come caricare un ViewController (XIB) da un costruttore di interfacce in un ViewController in codice. veloce veloce veloce
  • come rendere inseribile NSAttributedString Sposta ad un altro ViewController Swift
  • come presentare il nuovo ViewController e cancellare la corrente dalla memoria
  • Swift 4.2: come incorporare UIPageControl nel ViewController (senza Storyboard)?
  • come ripristinare lo stato del ViewController iniziale?
  • come trasferire i dati ad un altro titolare del trattamento per eliminare il ViewController?
  • come posso presentare una vista personalizzata modalmente senza utilizzare il ViewController?
  • come passare i dati da NSObject ad un altro ViewController quando si fa clic su TableViewCell?
  • come posso aggiungere una vista comune a più ViewController in iOS Swift?
  • come passare i dati dal ViewController al ViewController in una barra di schede iOS?
  • come utilizzare una vista di controllo per visualizzare più ViewController
  • c'è un modo per avere un atto di classe doganale su un UIView senza avere il ViewController passato (come riferimento) alla sua inizializzazione?
  • ritorno da un controller UIquiewController al primo ViewController
  • come passare un NSMutableArray ad un'altra classe di ViewController
  • come posso creare un ViewController con MapKit fisso sopra una TableView a scorrimento?
  • mostra l'errore ViewController
  • come rendere accessibile un oggetto delegato in un ViewController
  • non può convertire il valore di tipo 'ViewController' al tipo di argomento previsto 'UIButton' in Swift 4
  • come aggiornare un'etichetta di un ViewController dell'AppDelegate?
  • NSNotification: tentativo di presentare UIAlertController al ViewController la cui vista non è nella gerarchia delle finestre
  • comando push del ViewController in UITabBarController
  • iPhone X mostra un difetto visivo quando si preme un ViewController
  • come passare dal ViewController all'interno di ContainerView?
  • offset UISclollView da un bambino ViewController
  • come passare una cornice al ViewController incorporato?
  • rapido valore di passaggio ad un altro ViewController esistente
  • modifica del testo dell'etichetta del secondo ViewController facendo clic sul pulsante del primo ViewController senza vista
  • passaggio da un segno al ViewController ad un UITabBarController
  • imposta il valore nel ViewController casuale (sequenza casuale)