6

Sfondo: Desidero chiudere un modalView che ho presentato in precedenza e presentare immediatamente lo stesso viewController che ho appena archiviato con nuove informazioni.iOS: rimozione e presentazione di ModalViewController senza accesso al proprio controllore ViewController

Problema: non ho avuto molto successo in questo modo, senza un puntatore esplicito al genitore ViewController che ha presentato il primo ViewController modale. Sto cercando di scrivere questa classe che funziona senza fare i conti con il precedente codice viewController.

possibile vantaggio: Ci sono un paio di cose che ho avuto modo di sperimentare con:

1.) Cercando di ottenere l'accesso al genitore ViewController, che in questo momento non so come.

2.) Una volta che l'accesso al genitore è acquisita, posso semplicemente applicare il seguente codice:

UIViewController* toPresentViewController = [[UIViewController alloc] init]; 
    [self dismissViewControllerAnimated:YES completion:^{ 
     [parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES]; 
}]; 

In teoria questo dovrebbe funzionare dato l'accesso al genitore viewController. Sono aperto ad altri modi per farlo.

Assunzione: Non si dispone dell'autorizzazione per modificare alcun codice nel genitore ViewController.

risposta

11

Il tuo aspetto di codice come dovrebbe funzionare. Se si utilizza iOS 5, esiste una proprietà UIViewController denominata presentingViewController.

@property(nonatomic, readonly) UIViewController *presentingViewController; 

Quindi è possibile utilizzare questa proprietà per ottenere il controller di visualizzazione che ha presentato il controller modale.

Nota: In iOS 4 parentViewController verrebbe impostato al regolatore che presenta, quindi, se si stanno sostenendo sia iOS 4 e 5 si dovrà controllare la versione del sistema operativo prima di decidere quali proprietà per accedere. In iOS 5 Apple ha risolto il problema in modo che parentViewController sia ora utilizzato esclusivamente per i controllori di visualizzazione contenuti (vedere la sezione su Implementazione di un controller di visualizzazione contenitore nella documentazione UIViewController).

Edit: Per quanto riguarda l'accesso aiself.presentingViewController dal all'interno del blocco: Nel momento in cui il blocco viene chiamato (dopo il controller di vista modale è respinto) la proprietà presentingViewController può get set a zero. Ricordare che self.presentingViewController all'interno del blocco fornisce il valore della proprietà quando viene eseguito il blocco, non quando è stato creato.Per proteggersi da questo procedere come segue:

UIViewController* toPresentViewController = [[UIViewController alloc] init]; 
UIViewController* presentingViewController = self.presentingViewController; 
[self dismissViewControllerAnimated:YES completion:^ 
{ 
    [presentingViewController presentModalViewController:toPresentViewController animated:YES]; 
}]; 

Ciò è necessario non perché self è andato/respinto (è in sicurezza trattenuto dal blocco), ma perché non viene più esposta, quindi la sua presentingViewController è ora pari a zero. Non è necessario memorizzare lo presentingViewController altrove, la variabile locale va bene perché verrà mantenuta dal blocco.

+0

Se ho capito bene, dovrei cambiare questo codice: '[parentViewControllerAccessor presentModalViewController: toPresentViewController animato: YES];' a '[self.presentingViewController presentModalViewController: potatoPhotoVC animato: YES];'. Purtroppo, questo non sembra funzionare. Sto comprendendo qualcosa in modo errato? – Byte

+1

Ciò è probabilmente dovuto al modo in cui i blocchi conservano gli oggetti: manterrà il sé ma non il controller della vista che presenta, quindi quando il "sé" è stato rimosso questa proprietà potrebbe essere impostata su zero. Impostare self.presentingViewController su una variabile locale esterna al blocco, quindi utilizzare tale variabile all'interno del blocco. – jhabbott

+0

Questa è la stessa conclusione che ho trovato. Potrei dover creare una variabile statica per mantenere questo in modo tale che quando 'self' viene rimosso, il metodo funzionerà comunque. Ma sembra più un hack. – Byte

1

È possibile eseguire ciò utilizzando le notifiche.

Per esempio, il fuoco questa notifica da fuori vista modale quando si vuole che essere respinto:

[[NSNotificationCenter defaultCenter] postNotificationName:@"dismissModalView" 
                object:nil 
                userInfo:nil]; 

E poi gestire la notifica all'interno della vostra vista modale:

- (void)viewDidLoad { 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(dismissMe:) 
               name:@"dismissModalView" 
               object:nil]; 
} 

- (void)dismissMe:(NSNotification)notification { 
    // dismiss it here. 
} 
+0

"E poi gestire la notifica all'interno della vostra vista modale:" Non sono sicuro che cosa questo supponiamo di dire, ho ha detto esplicitamente, non posso toccare il codice sul precedente viewController che presenta questo viewController. A meno che non fraintenda qualcosa qui? – Byte

1

la soluzione per iOS5:

-(void)didDismissModalView:(id)sender { 

    // Dismiss the modal view controller 
    int sold=0; 

    if(sold==0){ 

     //Cash_sold.delegate = self; 
     // Cash_sold.user_amount.text=[NSString stringWithFormat:@"%d",somme]; 

     Cash_sold = [[CashSoldview alloc] initWithNibName:@"CashSoldview" bundle:nil]; 
     CGRect fram1 = CGRectMake(200,20,400,400); 
     Cash_sold.view.superview.frame = fram1; 
     Cash_sold.view.frame=fram1; 
     Cash_sold.modalTransitionStyle= UIModalTransitionStyleCoverVertical; 
     Cash_sold.modalPresentationStyle=UIModalPresentationFormSheet; 

     UIViewController* presentingViewController = self.parentViewController; 

     [self dismissViewControllerAnimated:YES completion:^ 
     { 
     [presentingViewController presentModalViewController:Cash_sold animated:YES]; 
     }];  
    } 
} 
1

Provate il seguente codice:

[self dismissViewControllerAnimated:NO 
         completion:^{ 
    // instantiate and initialize the new controller 
    MyViewController *newViewController = [[MyViewController alloc] init]; 
    [[self presentingViewController] presentViewController:newViewController 
               animated:NO 
               completion:nil]; 
}]; 
+0

codice molto breve e funziona anche bene .. – svmrajesh

Problemi correlati