2014-12-14 15 views
5

Zdaję sobie sprawę, że didRotateFromInterfaceOrientation jest przestarzałe w iOS 8; Mam jednak aplikację, która musi pozostać zgodna z iOS7. Problem polega na tym, że kiedy urządzenie jest obracane (w tym przypadku iPad), ta metoda jest wywoływana dwukrotnie. Dzieje się tak zarówno na rzeczywistym urządzeniu, jak i na symulatorze. Po prostu umieściłem NSLog w metodzie, aby to pokazać.didRotateFromInterfaceOrientation wypalanie Dwa razy podczas obracania

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 

     NSLog(@"didRotateCalled"); 
} 

Sprawdziłem również willRotateToInterfaceOrientation, ale ten działa poprawnie tylko raz zostaje wywołany.

Masz jakieś pomysły, dlaczego metoda didRotateFromInterfaceOrientation byłaby uruchamiana dwa razy na obrót?

Jako szybka aktualizacja. Postawiłem punkt przełomowy, w którym odkryłem coś interesującego. Ten widok to UISplitviewcontroller i wygląda na to, że metoda jest najpierw wywoływana dla UISplitviewcontroller, a następnie jako UIViewController. Nie wiem, dlaczego ...

Kilka dodatkowych informacji. Używam Storyboards one dla iPhone'a i innego iPada. IPhone nie korzysta z splitViewController. Podstawa kod jest dzielona tak w prepareForSegue I wykonaj następujące czynności:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
{ 
      UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController; 
      splitViewController.delegate = segue.destinationViewController; 
} 
+0

Wydrukuj "fromInterfaceOrientation". Co dostajesz? –

+1

wymień używane klasy ViewController i miejsce, w którym zaimplementowano 'didRotateFromInterfaceOrientation'.Być może twoja metoda jest wywoływana z różnych instancji lub z kodu w klasie i nadklasie. – Christian

+0

Podział master jest kontrolerem UITableViewController, a część szczegółowa jest kontrolerem UIViewController. Po wybraniu komórki po stronie wzorcowej szczegóły zostają "zastąpione" odpowiednią treścią. Możesz zobaczyć w moim kodzie powyżej konfiguracji dla tego w preareForSegue. – C6Silver

Odpowiedz

3

mam odpowiedź. Właśnie pobrałem symulatory dla iOS 7.1 do użytku w najnowszym Xcode. Zauważyłem, że metoda viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator NIE jest wywoływana podczas działania w systemie iOS 7.1. Jednak odkryłem również, że problem opisany przeze mnie przy rotacyjnym uruchamianiu dwa razy NIE zdarza się przy metodzie willRotateToInterfaceOrientation w iOS7, ale znowu działa w iOS 8. Jest to wyraźny błąd w Apple.

Wygląda na to, że będę musiał wykryć wersję systemu operacyjnego, na którym działa klient, a jeśli jest to system iOS 8 lub nowszy, nie będę wykonywał żadnego kodu w metodzie willRotateToInterfaceOrientation. Mogę jednak pozostawić tam metodę viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator dla urządzeń z systemem iOS 8, ponieważ ta metoda będzie po prostu ignorowana przez iOS 7.

Nie wiem, czy jest to problem dla kontrolerów splitview lub dla wszystkich metod widoku z rotacją między iOS 7 a 8. Jeśli Twoja aplikacja nie przesłania tej metody, nigdy nie wiesz. Jeśli to ty będziesz musiał zmierzyć się z tym, co zrobiłem powyżej. Niedobrze.

Oto kod używam do sprawdzenia wersji:

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    if (NSFoundationVersionNumber == NSFoundationVersionNumber_iOS_7_1) // use this only for iOS7 devices as otherwise this fires twice under iOS8 
    { 
     ... 
    } 
} 

Zostawiłem -(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator sposób jak to będzie po prostu ignorowana przez iOS 7 urządzeń, ale zostanie wywołana przez iOS 8.x i przypuszczalnie powyżej .

1

Mam ten sam problem (choć w moim przypadku funkcja willRotate zostanie również dwukrotnie wykonana na iOS 8). I stosuje się następujące rozwiązania:

BOOL _willRotate; // iVar for the state 

// Methods that should be called from willRotate/didRotate (can be inline) 
- (BOOL)workaroundIOS8RotationMethodsCalledTwice_forWillRotate_shouldExecute 
{ 
    if(_willRotate) { 
     return NO; 
    } 
    _willRotate = YES; 
    return YES; 
} 

- (BOOL)workaroundIOS8RotationMethodsCalledTwice_forDidRotate_shouldExecute 
{ 
    if(_willRotate) { 
     _willRotate = NO; 
     return YES; 
    } 
    return NO; 
} 

// Inside willRotate (return if shouldn't execute): 
if(![self workaroundIOS8RotationMethodsCalledTwice_forWillRotate_shouldExecute]) { 
    return; 
} 

// Inside didRotate (return if shouldn't execute): 
if(![self workaroundIOS8RotationMethodsCalledTwice_forDidRotate_shouldExecute]) { 
    return; 
} 
0

I znaleziono viewWillTransition wywoływana dwukrotnie na różnych UIViewController przypadkach. Podczas pierwszego połączenia self jest prawidłową instancją. Ale przy drugim wywołaniu, jaźń jest nieważna. viewDidLoad() nie jest wywoływany w tym nieprawidłowym wystąpieniu. Dodaję członka i ustawię wartość na viewDidLoad, a następnie sprawdź, czy self jest poprawne, czy nie.

class MyViewControler: UIViewController { 
    var last_width:CGFloat? 

    override func viewDidLoad() { 
    super.viewDidLoad() 
    print(" viewDidLoad self \(self) has address: \(Unmanaged.passUnretained(self).toOpaque())") 
    last_width = self.view.bounds.width 
    } 

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
    print(" viewWillTransition self \(self) has address: \(Unmanaged.passUnretained(self).toOpaque())") 
    // Bug? viewWillTransition called twice with diffent self instance, ignore second call 
    if (last_width == nil || last_width == size.width) { 
     return 
    } 
    last_width = size.width 
    } 
} 
Powiązane problemy