2015-03-31 21 views
14

Używam loginu Twitter w procesie rejestracji mojej aplikacji. I proszę o adres e-mail użytkownika. Kiedy go otrzymam, chciałbym przedstawić kontroler UIAlertController.Swift Próba przedstawienia kontrolera UIAlertController, którego widok nie znajduje się w hierarchii okna (prezentowane po TWTRShareEmailViewController)

Oto mój kod:

func askForTWMail(){ 
    if (Twitter.sharedInstance().session() != nil) { 
     let shareMailVC=TWTRShareEmailViewController(completion: {(mail:String!, error:NSError!) in 
      if (mail != nil) { 
       print("GOT MAIL: \(mail)") 
       self.gotMail() 
      }else{ 
       print("MAIL VC ERROR: \(error)") 
      } 
     }) 
     println("PRESENT MAIL VC") 
     self.presentViewController(shareMailVC, animated: true, completion: nil) 
    }else{ 
     println("User not logged in") 
    } 
} 

func gotMail(){ 
    var alertController=UIAlertController(title: "Some title", message: "Some message", preferredStyle: UIAlertControllerStyle.Alert) 
    var okAction=UIAlertAction(title:"Yes", style: UIAlertActionStyle.Default) { 
    UIAlertAction in 
    //some action 
    } 
    var cancelAction=UIAlertAction(title:"No", style: UIAlertActionStyle.Cancel){ 
    UIAlertAction in 
    //some action 
    } 
    alertController.addAction(okAction) 
    alertController.addAction(cancelAction) 
    self.presentViewController(alertController, animated: true, completion: nil)     
} 

Ale ten błąd (chyba dlatego, że TWTRShareEmailViewController nie zostaje odrzucona):

Ostrzeżenie: próba przedstawienia UIALertController na xViewController którego widok nie jest w hierarchii okien!

Masz pomysł, jak mam to napisać? Skąd mam wiedzieć, kiedy TWTRShareEmailViewController został odrzucony, aby kontynuować proces rejestracji i móc przedstawić moją UIAlertController? Nie jestem świadomy metody delegatów związanych z TWTRShareEmailViewController.

Każda pomoc jest doceniana. Dzięki.

Odpowiedz

31

Znaleziono rozwiązanie here. Prawdopodobnie robię to źle, ale jeśli nie, może to być błąd Apple'a. Rozwiązaniem jest opóźnić prezentację UIAlertController:

dispatch_async(dispatch_get_main_queue(), ^{ 
    self.presentViewController(alertController, animated: true, completion: nil) 
}) 

EDIT: Znalazłem inną obejście (nie używać roztworu Odłożyłem już tutaj). Musiałem to zmienić, ponieważ logowanie na Twitterze również przerywało moje przejścia między VC.

Teraz nazywam konkretną UIViewController (nazwałem ją czymś w rodzaju TWLoginVC), w której robię wszystkie dane logowania na Twitterze i inne rzeczy. Widok jest po prostu czarny, więc użytkownik nie widzi, że proces jest wykonywany w innym VC (wystarczy, że wybierze użytkownika Twittera, z którym chce się zalogować). Wydaje mi się, że możesz również umieścić jasne tło, które będzie jeszcze bardziej niewidoczne.

Po wywołaniu tego kontrolera widoku i jego odrzuceniu, przejście nie jest do niego stosowane i nie mam z nim żadnego problemu.


EDIT Aktualizacja Swift:

DispatchQueue.main.async{ 
    self.present(alertController, animated: true, completion: nil) 
} 
+0

Czy znalazłeś lepsze rozwiązanie dla tego problemu? Używam również dispatch_async –

+0

Jak wyjaśniłem w mojej zredagowanej odpowiedzi, mam specjalny VC na Twitterze. Więc kiedy użytkownik chce się zalogować na Twitterze, modalnie przedstawiam mój "TWLoginVC", gdzie wszystko jest zrobione (unikanie dziwnego zachowania w niektórych przypadkach, ze specjalnymi przejściami między VC na przykład). Ale trochę zmieniłem kod i nie muszę już pokazywać kontrolera UIAlertController. Więc nie żałuję, że nie mam lepszego rozwiązania:/ –

+1

Z nowym TwitterKit (właśnie zaktualizowałem go do wersji 2.0.2), sposób zmiany adresu e-mail użytkownika. Zostało to wyjaśnione w dokumencie na Twitterze: https://docs.fabric.io/ios/twitter/request-user-email-address.html. –

5

Oto uaktualniony odpowiedź na Swift 3 testowany na Xcode 8 na podstawie odpowiedzi Marie DM.

DispatchQueue.main.sync { 
    self.present(alertController, animated: true, completion: nil) 
} 
-1

Jeśli DispatchQueue.main.sync spowodowane zgniatać, spróbuj DispatchQueue.main.async. "async" działał na mój problem podczas powrotu z contactPicker().