6

Próbowałem kilka odpowiedzi na tej stronie, ale żaden z nich nie wydają się odnosić do mojego problemuLekceważenie zarówno widoki UINavigation i poglądów modalnych na raz programowo

Mam app MasterDetail który ma dwa rodzaje segues że Ja używam. Po naciśnięciu przycisku w widoku szczegółowym używa on segmentu wypychania i przesuwa na niego inny szczegółowy widok. W nowym widoku szczegółowym (tym, który został właśnie wciśnięty) znajduje się przycisk, który wywołuje kolejne UIView (arkusz formularza) za pomocą modalnego segue.

Co usiłuję zrobić jest, gdy użytkownik wybierze rzędzie UIAlertView pojawi się wyświetlając komunikat, podczas gdy w tym samym czasie (nie musi być w tym samym czasie ) to oddala UIViewController (modalny) i wraca z podświetlonego kontrolera Viewcontroller. Zasadniczo, potrzebuję być w stanie odrzucić wszystkie kontrolery viewcontroller, jeden modal i jeden push (nav), aby widok powrócił do oryginalnego głównego ekranu, z którego zaczęli.

Mam UIAlertView działa dobrze i mogę uzyskać modalne viewcontroller do zwolnienia za pomocą [self.dismissViewControllerAnimated:YES completion:nil];, ale nie wiem, jak odrzucić następny Viewcontroller (który jest w kontroler nawigacji). Używanie tego: [self.navigationController popToRootViewControllerAnimated:NO]; nie działa.

Tu jest miejsce, gdzie chcę, aby wywołać funkcję, aby usunąć wszystkie widoki:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlWithIDAndChallenge]; 

    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

    UIAlertView *message = [[UIAlertView alloc] [email protected]"Started" message:@"The challenge has begun!" delegate:nil cancelButtonTitle:@"OK!" otherButtonTitles:nil]; 

    [message show] 

    //right here is where I would normally dismiss the modal VC 
    //here is where I would like to dismiss all VC 

} 
+0

Jakie wersje iOS ty nośną? Jeśli używasz tylko iOS 6 i późniejszych wersji, możesz użyć odwijania sekwencji, które robią to bardzo wdzięcznie. – Rob

+0

@Rob Używam iOS6 – CaptJak

+0

To uczucie, gdy znalazłem odpowiedź na moje pytanie w TWOIM pytaniu. Wielkie dzięki. –

Odpowiedz

14

Jeśli chcesz, w projektach iOS 6.0 (i nowszych) możesz użyć opcji odpinania.Na przykład, można:

  1. W swojej górnej regulatora poziomu widoku (jeden chcesz odpocząć do, nie kontroler masz zamiar rozwijać z), napisać odwijania metodę Segue, w tym przypadku o nazwie unwindToTopLevel (osobiście uważam, że to przydatne, jeśli segue ponosi pewne wskazówki co do tego, co przeznaczenie segue jest, z powodów, które staną się oczywiste, gdy mamy do kroku 3, poniżej):

    - (IBAction)unwindToTopLevel:(UIStoryboardSegue *)segue 
    { 
        NSLog(@"%s", __FUNCTION__); 
    } 
    
  2. W scenie programu budującego interfejs z whi ch można zainicjować zrelaksować, kontrolę ⌘ -Przeciągnij z ikoną widok kontrolera do ikony wyjścia do stworzenia odwijania segue:

    enter image description here

    Generalnie chcesz zdefiniować segue od przycisku do wyjścia wylot (i gotowe), ale jeśli chcesz wywołać programowo, możesz utworzyć go między kontrolerem a gniazdkiem rozwijanym, jak pokazano powyżej.

  3. dostaniesz trochę pop-up, który zawiera nazwę firmy odwijania segues (od prezentujących kontrolerów ... to jest jak magia):

    enter image description here

  4. Jeśli masz zamiar powoływać się na to segue programowo, trzeba zaznaczyć, że odwijania segue w zarysie dokumentu po lewej stronie okna programu IB, a raz to zrobisz, możesz dać się odprężyć segue storyboard ID:

    enter image description here

    Generalnie używam nazwy odpinanego segue dla id storyboardu, ale możesz użyć tego, co chcesz.

  5. Teraz zrobiwszy, że Twój alert widok może wywołać segue:

    - (IBAction)didTouchUpInsideButton:(id)sender 
    { 
        [[[UIAlertView alloc] initWithTitle:nil message:@"go home" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil] show]; 
    } 
    
    #pragma mark - UIAlertViewDelegate 
    
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
    { 
        if (buttonIndex != [alertView cancelButtonIndex]) 
        { 
         [self performSegueWithIdentifier:@"unwindToTopLevel" sender:self]; 
        } 
    } 
    
+0

Dziękuję za odpowiedź graficzną, bardzo pomaga! Jeśli spojrzysz na komentarz i edycję na moje pytanie, zobaczysz, że nie używam funkcji UIAlertView, tak jak to pokazałeś. Biorąc pod uwagę to, w jaki sposób wykonam segue? po prostu wsadzić go tam, gdzie umieszczam komentarz? – CaptJak

+0

OK, umieściłem go tam, gdzie umieszczam komentarz powyżej i nic się nie dzieje. W logu widzę to: '- [blahViewController unwindToTopLevel:]'. IBAction nie wydaje się być połączony z niczym (koło obok jest puste). Czy to gdzieś się połączy? – CaptJak

+0

@CaptJak Biorąc pod uwagę, że widoki alertów działają asynchronicznie, nie chcę wyświetlać alertu, a następnie odrzucać widoki, gdy alert jest nadal wyświetlany i zanim użytkownik go odrzuci (może działać, ale wydaje się dziwnym przepływem UI).Zrobiłbym to tak, jak w mojej odpowiedzi (nie przesuwaj, dopóki użytkownik nie kliknie przycisku w alarmie), albo możesz zamiast tego wyświetlić "viewDidAppear" tego kontrolera najwyższego poziomu. (mógłbyś mieć jakąś właściwość klasy, która dyktowałaby, czy alert zostanie pokazany, czy nie, i ustawić go w 'prepareForSegue' w kontrolerze _from_, który przenosisz.) – Rob

0

Można spróbować wymienić [self.dismissViewControllerAnimated:YES completion:nil]; z

self dismissViewControllerAnimated:YES completion:^{ 
    [parentViewController.navigationController popToRootViewControllerAnimated:YES]; 
} 

wierzę parentViewController będzie wskazywać na widoku kontrolera przedstawienia, i blok spowoduje, że kontroler nawigacyjny kontrolera nadrzędnego pojawi się w kontrolerze widoku głównego.

1

Od klasy ty przedstawiony swoją modalne widok

wezwanie oddalenie modalnych, a następnie wykonać selektora po pewnym opóźnieniem, a następnie wykonaj

Oto przykładowy kod

//Write this in the class from where you presented a modal View. 
//Call the function from modal class when you want to dismiss and go to root. 
- (void) dismissAndGoToRoot { 
     [self dismissViewControllerAnimated:YES completion:nil]; 
     [self performSelector:@selector(gotoRoot) withObject:nil afterDelay:0.50]; 
} 

- (void)gotoRoot { 

    [self.navigationController popToRootViewControllerAnimated:NO]; 
} 

Tu będzie zadzwoń do funkcji

// tutaj jest miejsce, gdzie normalnie odrzuciłbym modalny VC // tutaj jest miejsce, w którym ould chciał odrzucić wszystkie VC

[self.parentViewController dismissAndGoToRoot]; 

Jeśli to nie poskutkuje, to wziąć instancję zmiennej ParentViewController w modalnej klasy i przypisać prezentując modalne kontroler widoku.

+0

Dobra, myślę, że ten kod jest dla mnie poprawny. Nie jestem pewien jak to nazwać, ponieważ mój UIAlertView (który, gdy zwalniany powinien wywoływać twoją funkcję) nie jest jego własną funkcją, ale jest w 'didSelectRowAtIndexPath'. Jak mógłbym zadzwonić do ciebie, by zareagować, kiedy UIAlert zostanie oczyszczony? Dodałem moje 'didSelectRowAtIndexPath' do mojego pytania – CaptJak

+0

@CaptJak zobacz edytowaną odpowiedź. –