Niezrównoważone wywołania rozpoczynające / kończące przejścia między wyglądami dla <FirstViewController: 0x2a2c00>

93

Mam ten problem, gdy symuluję moją aplikację, nie jest to błąd ani ostrzeżenie, ale pojawia się w mojej konsoli. Czy ktoś kiedykolwiek wcześniej tego doświadczył?

C. Johns
źródło
czy tworzysz jakąś animację w tym kontrolerze widoku?
1
Tak. Mam animację otwierającą, która rozsuwa się na obrazy, zauważyłem, że ten błąd występuje tylko wtedy, gdy ładuję kod na telefon.
C. Johns
komunikat o błędzie sugeruje rozpoczęcie przejścia, ale brakuje wywołania odpowiedniej metody zakończenia.
1
Mam to samo. Jakieś rozwiązanie?
seeafish
Również szukam rozwiązania tego
problemu

Odpowiedzi:

48

W moim przypadku ten błąd pojawia się, gdy bardzo szybko klikniesz dwie karty w widoku tabeli.

Rezultat powoduje błędną nazwę tytułu, przycisk Wstecz znika. Ktoś wspomniał, że podczas pchania widoku set animated:NO. Błąd zniknie, ale nadal powoduje dziwne zachowanie. Przesuwa dwa widoki, a następnie musisz dwukrotnie cofnąć się, aby wrócić do ekranu widoku tabeli.

Metoda, którą próbowałem, aby rozwiązać ten problem:

Dodaj BOOL cellSelected;

w viewWillAppear cellSelected = YES;

w delegacie didselectcell if (cellSelected){cellSelected = NO; do action ; }

Zapobiega to szybkiemu kliknięciu dwóch różnych komórek.

Chochołowska 228
źródło
5
Domyślam się, że niektóre sformułowania były trudne do zrozumienia. Dokonałem kilku zmian, aby zwiększyć czytelność.
Kyle Clegg,
42

W moim przypadku stało się to, gdy uruchomiłem [self performSegueWithIdentifier:@"SomeIdentifier" sender:self];w ramach metody UINavigationControllerelementu viewDidLoad.

Przeniesienie go do viewDidAppearmetody rozwiązało problem.

Powodem bardzo prawdopodobnym jest to, że viewDidLoadnie wszystkie fantazyjne animacje zostały już ukończone, podczas gdy viewDidAppearwszystko jest zrobione.

tttthomasssss
źródło
Dzięki. Zagubiłem się w erze jaskiniowców, w której tworzyłem każdy kod elementu interfejsu użytkownika. Storyboardy są dla mnie nowe.
Kiran Kulkarni
21

Ja też mam ten problem. Znalazłem dwa rozwiązania tego problemu:

  1. Możesz zobaczyć to rozwiązanie powyżej.
  2. Znalazłem podklasę, z UINavigationControllerktórej ten problem został rozwiązany. Buforowany kontroler nawigacji
Igor_CodabraSoft
źródło
15

Aby tego uniknąć, należy uruchomić kod w innej pętli

 double delayInSeconds = 0.1;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            // Put your code here
[self presentViewController:self.yourModalVC animated:YES completion:nil];
        });
prohuutuan
źródło
7
Lepszym pomysłem jest umieszczenie animacji prezentującej dispatch_asyncw głównej kolejce. Chodzi o dispatch_asyncto, że czeka, aż wszystkie inne animacje w głównej kolejce zostaną zakończone. jest to o wiele lepsze niż używanie opóźnienia, ponieważ: 1 - nigdy nie dowiesz się, czy opóźnienie jest wystarczające, zależy to od urządzenia hosta 2 - w końcu przesadzisz z opóźnieniem i coś się opóźni. spróbuj tego:dispatch_async(dispatch_get_main_queue(), ^{[self presentViewController:self.yourModalVC animated:YES completion:nil];});
M. Porooshani,
12

Miałem wiele problemów z tym samym problemem. Rozwiązałem to w ten sposób

1) Nie używasz UIViewController'swyznaczonego inicjatora initWithNibName:bundle:. Spróbuj go użyć zamiast po prostu init.

2) ustawione animated:YESna NIE i to rozwiązało problem. na przykład.[self.navigationController pushViewController: viewController_Obj animated:NO];

kunalg
źródło
7

Miałem ten sam problem podczas korzystania z kontrolera nawigacji i pchania do niego innych kontrolerów. Próbowałem użyć buforowanego kontrolera nawigacji i kilku innych podejść, ale to nie zadziałało. Po spędzeniu trochę czasu na zastanowieniu się, zauważyłem, że ten problem występuje, jeśli próbujesz wypchnąć nowy kontroler widoku podczas poprzedniej transakcji (animacji) w toku (chyba około 0,5 sekundy). W każdym razie szybko rozwiązałem problem, delegując kontroler nawigacji i czekając na zakończenie poprzedniej animacji.

dimanitm
źródło
Dziękuję Ci! Przeniesienie logiki do viewDidAppear pomogło w mojej sytuacji.
Jaroslav,
7

Upewnij się, że nie zapomnij użyć opcji -viewWillAppear, -viewDidAppear, -viewDidLoad, -viewWillDisappear, -viewDidDisappear, aby wywołać odpowiednią super metodę w przeciążeniu tych metod. Na przykład w moim przypadku źle dopasowałem nazwę metody w ten sposób:

-(void)viewDidAppear
{
 [super viewDidDisappear];
 //some code staff
 ..
}

Zauważ, że metody pojawiania się i znikanianiedopasowane

Nikolay Shubenkov
źródło
Właśnie spędziłem około dwóch godzin na debugowaniu tego problemu i tak się okazało. Wołanie super.viewWillAppear()wewnątrz viewDidDisappear().
Daniel Wood
Dzięki za tę wskazówkę. To nie był mój jedyny problem, ale pomogło!
Anthony C
4

„Niezbalansowane wezwania do rozpoczęcia / zakończenia zmian wyglądu dla”

Mówi, że animacja została uruchomiona, zanim ostatnia powiązana animacja nie zostanie wykonana. Więc czy wyskakujesz jakiś kontroler widoku przed wypchnięciem nowego? A może wyskakuje do roota? jeśli tak, spróbuj zrobić to bez animacji, np[self.navigationController popToRootViewControllerAnimated:NO];

I zobacz, czy to rozwiązuje problem, w moim przypadku to załatwiło sprawę.

nieskończona pętla
źródło
1
To jest klucz: pop lub zmień inne przejścia kontrolera widoku w tym samym czasie.
Rocky
2

Wystąpił ten problem, ponieważ wywoływałem UIPrintInteractionController z viewController bez UITabbar i ani UINavigationBar. Wygląda na to, że UIPrintInteractionController nie uzyskał poprawnego printInteractionControllerParentViewController. Zaimplementowanie metody w delegacie i zwrócenie bieżącego rootViewController działało dla mnie.

    - (UIViewController*)printInteractionControllerParentViewController:(UIPrintInteractionController*)printInteractionController;
balooka
źródło
2

Miałem podobny problem z przewijaniem modalnych okien dialogowych. Opublikowałem rozwiązanie tutaj ...

https://stackoverflow.com/a/38795258/324479

[Problem]

Nav Controller -> VC1 -Push -> VC2 -PopOver lub Modal Segue -> VC3.

VC3 powraca do VC1.

Gdy płynność z VC2 do VC3 jest PopOver i Modal, odwijanie kończy się ostrzeżeniem: Niezbalansowane wywołania rozpoczynające / kończące przejścia między wyglądami dla UIViewController "

Jeśli Segue od VC do VC jest popchnięte, ostrzeżenie zniknie.

[Rozwiązanie]

Byłoby wspaniale, gdyby zajęła się tym logika odprężenia. Może to błąd, może nie. Tak czy inaczej, rozwiązaniem jest uczynienie VC2 (kontrolera, który ma wyskakujące okienko) celem przewijania do tyłu, a następnie poczekaj, aż zakończy się pojawienie, zanim pojawi się kontroler nawigacji. Zapewnia to, że animacja przewijania do tyłu (wyskakujące okienko do tyłu) ma wystarczająco dużo czasu na zakończenie, zanim przejdzie dalej. Nawet przy wyłączonych animacjach nadal musi czekać, bo inaczej pojawi się błąd.

Twój kod dla VC2 powinien wyglądać następująco. (Szybki)

class VC2: UIViewController {
    private var unwind = false
    @IBAction func unwindToVC1(segue:UIStoryboardSegue) {
        unwind = true
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        if unwind {
            self.navigationController?.popViewControllerAnimated(false)
        }
    }
}
Carter Medlin
źródło
1

Taka sytuacja może wystąpić, jeśli dodajesz widok z kontrolerem widoku modalnego jako widok podrzędny. Najlepsze w użyciu:

-(void) viewDidAppear:(BOOL)animated {
    [self presentViewController:self.yourModalVC animated:YES completion:nil];
}

Zasadniczo oznacza to, że cykl życia widoku nie jest usprawniony dla tych kontrolerów widoku, które próbujesz wtedy wyświetlić.

elliotrock
źródło
1

Mam podobny problem, próbując zrobić:

[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:2] animated:YES];

w funkcji takiej jak - (void) popUpToLevelTwo;, i umieszczenie return;na końcu funkcji rozwiązuje problem

BabyPanda
źródło
1

Mam to również na

[self dismissModalViewControllerAnimated:YES];

Zmieniłem na YESa NOi to rozwiązało problem.

DD.amor
źródło
1

Mam ten sam problem, gdy użyłem metody pop navigationControllera W mojej aplikacji używam osobnej logiki dla kontrolera nawigacji, więc unikałem używania paska nawigacji i jest on zawsze ukryty. Następnie używam niestandardowego widoku i powiadomienia do obsługi przycisku Backbutton i jego zdarzeń. obserwatorzy powiadomień są rejestrowani i nie są usuwani. Tak więc powiadomienie odpala się dwukrotnie i tworzy wyżej wspomniany błąd. Sprawdź dokładnie swój kod, aby uzyskać takie błędy

Dileep Stanley
źródło
1

Co jest warte, mam ten sam błąd, gdy nie uwzględniam wywołania [super viewDidLoad:animated]w moim viewDidLoadzastąpieniu.

Raeldor
źródło
1
może masz na myśli ViewDidAppear? viewDidLoad nie ma parametrów
Fabio Napodano,
1

Miałem też ten problem, gdy nacisnąłem przycisk z NIB. Okazuje się, że przypadkowo podłączyłem przycisk do wysyłania zdarzenia do dwóch metod IBAction, z których każda wykonała pushViewController: animated:

Martin Lockett
źródło
Dzięki !! oszczędzasz mój czas !!
VD,
1

Miałem zaimplementowaną logikę, aby czekać, pchając, UIViewControlleraż wszystkie dane zostaną pobrane. Wystąpił błąd w tej logice, który spowodował wypchnięcieUIViewController zbyt wcześnie, gdy było jeszcze inne wywołanie API w toku.

Spowodowało to, że ten sam UIViewControllerzostał dwukrotnie popchnięty przez UINavigationControlleri dał to ostrzeżenie.

Jaspis
źródło
1

Powodem komunikat: Komunikat ten wyświetlany się wtedy i tylko wtedy, gdy są pchania / przedstawienie innego kontrolera Widok z viewWillAppear, loadView, initlub viewDidLoadmetoda bieżącego widoku kontrolera

Sposób na usunięcie komunikatu o błędzie: Przenieś swój kod wypychający / prezentujący do viewDidAppearmetody rozwiąże problem

Mehul Thakkar
źródło
1

Szybki 4

Mój problem polegał na tym, że prezentowałem inny VC, zanim mój obecny skończył się renderować.

Rozwiązaniem było przedstawienie mojego nextVC po krótkim czasie.

CZEGO NIE NALEŻY ROBIĆ

override func viewDidLoad() {
    super.viewDidLoad() 
    self.present(MyNextVC(), animated: true, completion: nil)
}

CO POWINIENEŚ ZROBIĆ

override func viewDidLoad() {
    super.viewDidLoad() 
    //Wait until the view finished to be constructed
    perform(#selector(showMyNextVC), with: nil, afterDelay: 0.01)
}

@objc func showCityList() {
    self.present(MyNextVC(), animated: true, completion: nil)
}
Ugo Marinelli
źródło
4
Zamiast używać opóźnienia, umieściłbym kod w viewDidAppear lub viewDidLayoutSubviews.
Pranav Kasetti
0

Miałem ten problem, kiedy zapomniałem ustawić Break; po naciśnięciu widoku w instrukcji switch!

Jak tutaj:

case 1:{

        SomeViewController *someViewController = [[SomeViewController alloc]initWithNibName:@"SomeViewController" bundle:Nil];
        [self.navigationController pushViewController:someViewController animated:YES];
        [someViewController release];
    }

        break; //Forgetting to set break here:
Alex McPherson
źródło
0

Przyczyną błędu „Niesymetryczne wywołania do rozpoczęcia / zakończenia zmian wyglądu” jest nawigacja | segue dwa razy w tym samym czasie

poa
źródło
0

jednym rozwiązaniem byłoby,

[NSTimer scheduledTimerWithTimeInterval:0.05(or as required) target:self
selector:@selector(your_selector_method_to_push_the_view) userInfo:nil repeats:NO];
user3390994
źródło
0

Możesz na to napotkać, jeśli spróbujesz odrzucić UIViewController przed zakończeniem ładowania.

Miałem ten komunikat w konsoli i skupiałem się całkowicie na UIViewController, który prezentował nowy UIViewController, bez powodzenia. W końcu odkryłem, że problem występował w kontrolerze UIViewController, który prezentowałem, sam się odrzucał, ponieważ użytkownik nie był zalogowany na swoje konto.

Mam nadzieję, że to komuś pomoże.

Mark Hennings
źródło
0

To było dla mnie trudne: przeskoczyłem

override func shouldAutomaticallyForwardRotationMethods() -> Bool {
    return true
}

bez nadpisywania:

override func shouldAutomaticallyForwardAppearanceMethods() -> Bool {
    return true
}

w moim głównym kontrolerze nawigacji w oknie. następnie podrzędny kontroler nawigacyjny narzekał, pchając inny kontroler widoku z wyżej wymienionym ostrzeżeniem. Ostrzeżenie nie było najgorsze, duży problem polegał na tym, że tam delegat dziecięcego kontrolera nawigacyjnego nie był już wzywany. zmęczony.

heiko
źródło
0

W moim przypadku pobierałem NSDataod NSURLśrodka ' viewDidLoad'.

BhushanVU
źródło