2015-09-21 13 views
5

Używam odpinania odwijającego, aby rozwinąć początkowy kontroler widoku w moim scenorysie. Rozwijającej działa świetnie, I wdrożone tę metodę w moim początkowym kontrolerze widoku:iOS - cofnij się do mojego początkowego kontrolera widoku

- (IBAction) unwindToInitialViewController:(UIStoryboardSegue *) unwindSegue { 

} 

Jeśli jednak staram się segue do innego kontrolera widoku po robię odprężyć pojawia się następujący błąd:

Warning: Attempt to present on whose view is not in the window hierarchy!

Wygląda na to, że dzieje się tak tylko wtedy, gdy rozwijam kontroler widoku, który jest zaznaczony jako "Kontroler widoku początkowego" w scenorysie. Czy to błąd? Czy powinienem móc odpocząć na tym początkowym kontrolerze? Inne pomysły?

EDIT:

Oto jak wykonać drugą segue:

[self performSegueWithIdentifier:@"mySegue" sender:nil]; 

Należy zauważyć, że jest to problem logowania/wylogowania. Kiedy loguję się po raz pierwszy, następuje przejście z mojego kontrolera logowania do mojego następnego kontrolera. Kiedy się wylogowuję, rozwijam się do początkowego kontrolera widoku. Następnie loguję się ponownie i przejście z mojego kontrolera logowania do następnego kontrolera nie działa.

EDIT 2:

Z dalszych badań znalazłem jego ponieważ używam delegata dla mojego logowania. Logowanie jest asynchroniczne, nawiązuję połączenie z AFNetworking i po jego zakończeniu wzywam mojego delegata logowania (w tym przypadku login VC). W tym momencie login VC może przejść do widoku.

kod Login:

- (void) login: (NSDictionary *) parameters { 
    [http.manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, NSDictionary *response) { 
     [self.loginDelegate loginSuccess:response]; 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     [self.loginDelegate loginFailure:error]; 
    }]; 
} 

mój login VC, który jest delegatem:

- (void) loginSuccess:(NSDictionary *) response { 
    // setup user info based on response 
    ... 
    // Segue 
    [self performSegueWithIdentifier:@"loginSuccessSegue" sender:nil]; 
} 

Sprawdziłem, że jestem w głównym wątku, kiedy i ja segue i nadal nie ma szczęścia. Wiem, że AFNetworking zawsze nazywa bloki sukcesu/awarii również w głównym wątku.

Podstępna część. Jeśli zmienię powyższy kod, aby użyć bloku, a nie delegata, storyboard/segue nie zostanie pomieszany i mogę się zalogować i wylogować wiele razy bez problemu.

Dlaczego segue działa za pierwszym razem ze wzorem delegatów, ale w przypadku wylogowania (odwijania) nie mogę ponownie użyć tej opcji?

EDIT 3:

Więcej dochodzenie pokazuje, że na odpoczynek mój login VC viewDidAppear nazywa się dwukrotnie. Przy początkowym rozwijaniu widok wygląda na cały czas na stosie, pokazuje, że szybko się wyświetla i wywoływana jest metoda viewDidAppear. Jest to jednak animowane szybko i viewWillAppear jest nazywany po raz drugi z innym VC. Myślę, że to może być przyczyną problemu. Dlaczego, gdy odprężam się w tym VC, czy animowane jest tylko po to, aby zostać ponownie animowane?

+0

Jaki jest Twój początkowy viewController? Poza tym, jak sobie radzisz w drugiej segue? – JDM

+0

Wygląda na to, że zbyt szybko przejdziesz do następnego kontrolera. – kirander

+0

@Jay dodałem, jak programowo przenosić. – lostintranslation

Odpowiedz

1

Proszę sprawdzić, czy Twoja loginDelegate jest nil podczas drugiej próby logowania. Jeśli jest to nil, "połączenia delegatów" po prostu znikną. Należy również sprawdzić, czy loginDelegate wskazuje na wystąpienie, którego się spodziewasz.Jeśli wskazuje na "starą" instancję, można próbować przedstawić niewłaściwe widoki.

Zestaw metod viewDidLoad, viewDidAppear, viewWillAppear itp. Może być wywoływany w nieoczekiwanej kolejności, zwłaszcza po powrocie do nawigacji lub prezentacji reklamy i powrocie z niej. Jeśli masz różne zadania inicjowania/konfiguracji rozproszone wśród tych metod, możesz skończyć z częściowo zainicjowanym kontrolerem widoku.

(myślenie o problemie Straciłem swoje oświadczenie o napotkał błąd, więc prawdopodobnie delegat nie jest zerowa.)

EDIT:

Pobiegłem jeden z moich malutkich projektów badawczych odpoczynek i tam log połączeń viewDidAppear:

viewDidAppear: <ViewController: 0x7a687700> 
viewDidAppear: <VC2: 0x7a70e970> 
viewDidAppear: <VC3: 0x7a694d50> 
unwind target 
viewDidAppear: <VC2: 0x7a70e970> 
viewDidAppear: <ViewController: 0x7a687700> 
viewDidAppear: <VC2: 0x7a71b790> 
viewDidAppear: <VC3: 0x7a694d20> 
unwind target 
viewDidAppear: <VC2: 0x7a71b790> 
viewDidAppear: <ViewController: 0x7a687700> 

Robi się odprężyć w VC3 krótko pokazuje VC2 i ostatecznie kończy się na cel ViewController. Teraz drugie "logowanie" prowadzi do różnych instancji kontrolerów widoku.

Czy przechowujesz odniesienia do "starych" kontrolerów widoku?

Innym powodem może być to, że twoja detekcja "wylogowania" zostanie uruchomiona dwukrotnie (raz przy przechodzeniu wzdłuż rozwijania i jeszcze raz, gdy pośrednik lub początkowy kontroler widoku wykryje potrzebę zalogowania się?).

+0

To nie jest zero. Odbywa się wezwanie delegata. Segue próbuje przejść i nie może wyświetlać widoku, stąd komunikat o błędzie. – lostintranslation

+0

@lostintranslation Wysłałem odpowiedź i natychmiast przypomniałem komunikat o błędzie :-) Zaktualizowałem odpowiedź. –

+0

To samo wystąpienie :(Zweryfikowano w debuggerze – lostintranslation