2012-01-31 8 views
54

Mam kontroler widoku, który zawiera widok tabeli, elementy w tabeli można wybrać i poprawnie utworzyć kontroler widoku szczegółów."Niesymetryczne wywołania przejść dla początku/końca dla elementu DetailViewController" podczas przesuwania więcej niż jednego kontrolera widoku szczegółowego

Pozycje w tabeli przedstawiają elementy, które mogą zawierać powiązany z nimi wyzwalacz czasowy, a dla każdej pozycji zaplanowane jest powiadomienie lokalne, jeśli aplikacja znajduje się na pierwszym planie po wygaśnięciu powiadomienia lokalnego, a następnie w widoku szczegółowym dla elementu jest automatycznie wyświetlany.

Mam problem, który manifestuje się, gdy dwa powiadomienia wygasają w tym samym czasie, co powoduje, że widoki nie są wyświetlane poprawnie, a ponadto dzienniki konsoli: "Niezrównoważone wywołania przejść do początku/końca dla NNN", gdzie NNN jest mój kontroler widoku szczegółów.

tabela widok kontroler jest tworzony w następujący sposób:

self.tableViewController = [[TableViewController alloc] initWithNibName:@"TableView" bundle:nil]; 
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.tableViewController]; 
self.window.rootViewController = navController; 

Kiedy miejscowy zgłoszenie wygasa i didReceiveLocalNotification: wywoływana jest aplikacja nadaje powiadomienie za pomocą NSNotifcationCenter postNotificationName a do którego widok kontroler stolik nasłuchuje. Kiedy kontroler widoku tabeli otrzyma to powiadomienie tworzy kontroler widok szczegółów i popycha go na stosie jako:

[self.navigationController pushViewController:detailViewController animated:YES]; 

Czytałem gdzieś, że może być problem, jeśli kontroler widok popycha innego kontrolera widoku, gdy jest sam nie na górze stosu - więc pomyślałem, że to musi być problem, ponieważ gdy kontroler widoku tabeli otrzyma drugie powiadomienie, nie będzie już na wierzchu stosu nawigacji, ponieważ wcześniej popchnął kontroler widoku szczegółów na stos po otrzymaniu pierwszego powiadomienia.

Więc zmieniłem kod Push to:

[[self.navigationController topViewController].navigationController pushViewController:detailController animated:YES]; 

Ale to nie miało znaczenia.

Więc obok myślał że może być problem, bo pierwszy kontroler szczegółowy widok nie był już szansę w pełni pokazać przed 2 kontrolera widok był popychany - więc zmieniłem aplikacji zgłoszenia delegowania z użyciem:

[[NSNotificationCenter defaultCenter] postNotificationName: 

do

[[NSNotificationQueue defaultQueue] enqueueNotification: postingStyle:NSPostWhenIdle] 

Tak, że popycha nie nastąpi w tym samym iteraction pętli aplikacji. Ale to nie miało znaczenia, ani nie próbuje wprowadzić opóźnienie do pchania Widok szczegółowy controlle:

double delayInSeconds = 0.1; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    [[self.navigationController topViewController].navigationController  pushViewController:detailController animated:YES]; 
}); 

Nie mam pojęcia, na czym polega problem i co próbować dalej, jakieś pomysły?

+0

wdał się w podobnej sytuacji znalazł Fix: http://stackoverflow.com/questions/19500025/uinavigationcontroller-transition-animations-triggered-too-fast/19738292#19738292 –

Odpowiedz

108

„Połączenia niesymetryczne do rozpoczęcia/zakończenia przejścia wygląd”

występuje podczas próby i wyświetlić nową viewcontroller zanim obecny kontroler widok zakończeniu wyświetlania. Możesz go odtworzyć, przechodząc w viewWillAppear.

Zasadniczo próbujesz wcisnąć dwa kontrolery widoku na stos w tym samym czasie. Zaproponuj utrzymanie kolejki w sterowniku widoku tabeli, który utrzymuje listę szczegółowych widoków, które wymagają wyświetlania. Wciśnij jeden raz na stos i sprawdź wyjście z bieżącego widoku szczegółów, czy istnieją jakieś kolejkowe widoki szczegółów, które wymagają wyświetlania.

Ten rodzaj nawigacji może być mylący dla użytkownika. Lepszym rozwiązaniem może być rozważenie, aby widok szczegółów obsługiwał wiele elementów.

+0

zauważyłem kiedy używałem postNofictionName: wtedy viewDidAppear: nie był wywoływany dla pierwszego widoku przed pchnięciem drugiej.Jednak po zmianie na użycie enqueNotification: viewDidAppear jest wywoływane przed pchnięciem kontrolera 2 widoku (ponieważ popchnięcia zmieniły się z obu występujących w tym samym wywołaniu pętli uruchomieniowej w celu oddzielnej inwokacji pętli). Czy w związku z tą zmianą pierwszy widok nie zakończył się przed pojawieniem się drugiego naciśnięcia? Jednak problem nadal istnieje. – Gruntcakes

+2

Jedna z najbardziej pomocnych odpowiedzi z innych odpowiedzi na temat tego błędu. Czy mogę zapytać, skąd bierzesz wyjaśnienie? Spodziewam się, że dokumenty Apple pojawią się w Google podczas debugowania, ale nie mogłem znaleźć żadnych dokumentów na ten temat. –

2

Może się to również zdarzyć, gdy spróbujesz wydobyć VC ze stosu więcej niż jeden raz. W moim przypadku metoda, która wywołała VC była błędnie nazywana wielokrotnie. Kiedy to wyczyściłem, problem zniknął.

10

„niesymetryczne wzywa do rozpoczęcia/zakończenia przejścia wygląd”

Mówi animacja rozpoczyna się przed ostatnim powiązanym animacji isnt zrobić. Czy otwierasz dowolny kontroler widoku przed wypchnięciem nowego? A może popping to root? jeśli tak, spróbuj to zrobić bez animacji. tj.

[self.navigationController popToRootViewControllerAnimated:NO]; 

Sprawdź, czy to rozwiązuje problem. W moim przypadku to wystarczy.

7

"Wywołania niezbalansowanych przejść do początku/końca przejścia" pojawia się, gdy próbujesz wyświetlić nową kontrolkę viewcontroller przed wyświetleniem bieżącego kontrolera widoku.

Musisz więc być pewien, że nie przedstawisz nowego VC, dopóki pierwsza nie zakończy animacji.

Użyj didShowViewController i willShowViewController, aby zablokować prezentowanie nowego VC przed ukończeniem animacji. To dla backButtonAction, który tworzy popViewController z animacją: YES.

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
{ 
    [self.myNavView.backButton addTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside]; 
} 

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
{ 
    [self.myNavView.backButton removeTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside]; 
} 
+1

"Musisz więc być pewien, że nie przedstawisz nowego VC, dopóki pierwsze animacje się nie zakończą." ta linia działa dla mnie jak magia. Zeskanowany mój dzień. Dzięki!!! –

+0

Cieszę się, że mogę pomóc! – Gabriel

0

Spójrz na tych przeciążeń:

Jeżeli są puste, a następnie zauważyć je i odbudować.

- (void) beginAppearanceTransition:(BOOL) isAppearing animated:(BOOL)animated {} 
- (void) becomeActive:(NSNotification *) notification {} 
1

Właściwie trzeba poczekać, aż zakończy się animacja wypychania. Możesz więc delegować UINavigationController i uniemożliwić pchanie do czasu zakończenia animacji.

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{ 
    waitNavigation = NO; 
} 


-(void)showGScreen:(id)gvc{ 

    if (!waitNavigation) { 
     waitNavigation = YES; 
     [_nav popToRootViewControllerAnimated:NO]; 
     [_nav pushViewController:gvc animated:YES]; 
    } 
} 
-2

Czy używasz funkcji proxy wyglądu?

znalazłem bardzo problematyczne tę funkcję, ostatni raz mam

„asymetryczne połączenia do rozpoczęcia/zakończenia przejścia wygląd”

Rozwiązałem go usuwając metod [[UITextField appearance] ..].

Nadzieja to pomaga

Powiązane problemy