Piszę aplikację i muszę zmienić widok, jeśli użytkownik patrzy na aplikację podczas rozmowy przez telefon.
Wdrożyłem następującą metodę:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"viewWillAppear:");
_sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);
}
Ale nie jest wywoływane, gdy aplikacja powraca na pierwszy plan.
Wiem, że mogę wdrożyć:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
ale nie chcę tego robić. Wolę umieścić wszystkie informacje o moim układzie w metodzie viewWillAppear: i pozwolić, aby obsłużyły wszystkie możliwe scenariusze.
Próbowałem nawet wywołać viewWillAppear: from applicationWillEnterForeground :, ale nie wydaje mi się możliwe określenie, który jest obecnie kontrolerem widoku w tym momencie.
Czy ktoś wie, jak sobie z tym poradzić? Jestem pewien, że brakuje mi oczywistego rozwiązania.
ios
objective-c
iphone
viewwillappear
Philip Walton
źródło
źródło
applicationWillEnterForeground:
aby określić, kiedy aplikacja ponownie weszła w stan aktywny.isMemberOfClass
lubisKindOfClass
, w zależności od potrzeb.Odpowiedzi:
Metodę
viewWillAppear
należy brać pod uwagę w kontekście tego, co dzieje się we własnej aplikacji, a nie w kontekście umieszczania aplikacji na pierwszym planie po przełączeniu się z innej aplikacji.Innymi słowy, jeśli ktoś spojrzy na inną aplikację lub odbierze telefon, a następnie przełączy się z powrotem na twoją aplikację, która była wcześniej uruchomiona w tle, twój UIViewController, który był już widoczny, kiedy opuściłeś aplikację, „nie przejmuje się”, że tak powiem - jeśli o to chodzi, to nigdy nie zniknęło i jest nadal widoczne - i dlatego
viewWillAppear
nie jest nazywane.Odradzam dzwonienie do
viewWillAppear
siebie - ma określone znaczenie, którego nie powinieneś obalać! Refaktoryzacja, którą możesz zrobić, aby osiągnąć ten sam efekt, może wyglądać następująco:Następnie uruchamiasz również
doMyLayoutStuff
z odpowiedniego powiadomienia:Nawiasem mówiąc, nie ma gotowego sposobu na określenie, który jest „bieżącym” UIViewController. Ale można znaleźć sposoby na obejście tego, np. Istnieją metody delegowania UINavigationController do sprawdzania, kiedy jest prezentowany UIViewController. Możesz użyć czegoś takiego do śledzenia najnowszego UIViewController, który został zaprezentowany.
Aktualizacja
Jeśli układasz interfejsy użytkownika za pomocą odpowiednich masek automatycznej zmiany rozmiaru różnych bitów, czasami nawet nie musisz zajmować się „ręcznym” układaniem interfejsu - po prostu zajmuje się ...
źródło
self.navigationController.topViewController
skutecznie to zapewnia, a przynajmniej ten na górze stosu, który byłby bieżący, jeśli ten kod jest uruchamiany w głównym wątku w widoku kontrolera. (Może się mylić, nie bawiłem się zbytnio, ale wydaje się, że działa.)appDelegate.rootViewController
też będzie działać, ale może zwrócić aUINavigationController
, a wtedy będziesz potrzebować,.topViewController
jak mówi @MatthewFrederick.Szybki
Krótka odpowiedź
Użyj
NotificationCenter
raczej obserwatora niżviewWillAppear
.Długa odpowiedź
Aby dowiedzieć się, kiedy aplikacja wraca z tła, użyj
NotificationCenter
obserwatora zamiastviewWillAppear
. Oto przykładowy projekt, który pokazuje, które zdarzenia mają miejsce, kiedy. (Jest to adaptacja tej odpowiedzi na Cel C ).Przy pierwszym uruchomieniu aplikacji kolejność wyjściowa to:
Po naciśnięciu przycisku Home, a następnie przeniesieniu aplikacji z powrotem na pierwszy plan, kolejność wyjściowa jest następująca:
Więc jeśli były pierwotnie próbuje użyć
viewWillAppear
wtedyUIApplication.willEnterForegroundNotification
jest chyba to, co chcesz.Uwaga
Począwszy od iOS 9 i nowszych, nie musisz usuwać obserwatora. W dokumentacji czytamy:
źródło
Użyj Centrum powiadomień w
viewDidLoad:
metodzie ViewController, aby wywołać metodę, a następnie zrób to, co powinieneś zrobić wviewWillAppear:
metodzie.viewWillAppear:
Bezpośrednie dzwonienie nie jest dobrym rozwiązaniem.źródło
dealloc
metodą.viewWillAppear:animated:
, jedna z najbardziej mylących metod w zestawach SDK systemu iOS, moim zdaniem, nigdy nie jest wywoływana w takiej sytuacji, tj. przy przełączaniu aplikacji. Ta metoda jest wywoływana tylko zgodnie z relacją między widokiem kontrolera widoku a oknem aplikacji , tj. Wiadomość jest wysyłana do kontrolera widoku tylko wtedy, gdy jego widok pojawia się w oknie aplikacji, a nie na ekranie.Gdy aplikacja przechodzi w tło, najwyraźniej najwyższe widoki okna aplikacji nie są już widoczne dla użytkownika. Jednak w perspektywie okna aplikacji są one wciąż najwyższymi widokami i dlatego nie zniknęły z okna. Widoki te raczej zniknęły, ponieważ zniknęło okno aplikacji. Nie zniknęli, ponieważ zniknęli z okna.
Dlatego, gdy użytkownik przełącza się z powrotem na twoją aplikację, najwyraźniej wydają się pojawiać na ekranie, ponieważ okno pojawia się ponownie. Ale z perspektywy okna wcale nie zniknęły. Dlatego kontrolery widoku nigdy nie otrzymują
viewWillAppear:animated
wiadomości.źródło
Swift 4.2 / 5
źródło
Starając się maksymalnie ułatwić, zobacz poniższy kod:
źródło