Я пытаюсь показать UIAlertController в моем ViewController в функции, вызванной NSNotification. Однако я получаю сообщение об ошибке:NSNotification: попытка представить UIAlertController на ViewController, чей вид отсутствует в иерархии окон
Attempt to present <UIAlertController: 0x7fe013d05d40> on <submarine.ViewController: 0x7fe011f20370> whose view is not in the window hierarchy!
NSNotification размещен от блока завершения (обратного вызова я думаю) от чего-то еще в моем пользовательском интерфейсе. Поскольку это обратный вызов, он не отображается. Поэтому я думал, что попробую NSNotificationCentre решить проблему без использования rootViewController для отображения предупреждения.
Мой код:
override func viewDidAppear(animated: Bool) {
// Handle onboarding
if needsOnboarding() {
handleOnboarding() // This create the completion block that posts the NSNotification
}
NSNotificationCenter.defaultCenter().addObserver(self, selector: "showTermsAlert:", name:"showTermsAlert", object: nil)
}
func showTermsAlert(notification: NSNotification) {
let termsAlert:UIAlertController = UIAlertController(title: "Terms And Conditions", message: "Please view the terms below before accepting them.", preferredStyle: UIAlertControllerStyle.Alert)
termsAlert.addAction(UIAlertAction(title: "View Terms", style: .Default, handler: { (action: UIAlertAction!) in
UIApplication.sharedApplication().openURL(NSURL(string: "my_terms_url")!)
}))
termsAlert.addAction(UIAlertAction(title: "I Agree to the Terms", style: .Default, handler: { (action: UIAlertAction!) in
self.onboardingFinished()
}))
self.presentViewController(termsAlert, animated: true, completion: nil)
}
Кто-нибудь есть идея, почему это происходит? Я не понимаю, почему это не в иерархии окон - оно отображается с помощью viewController self
и создается в функции верхнего уровня внутри VC.
Спасибо!
EDIT: оригинальный код внутри handleOnboarding()
в:
библиотека используется: Onboard
func handleOnboarding() {
let secondPage = OnboardingContentViewController(title: "What's going on?", body: "Submarine routes your data through our network, around any filters and restrictions, giving you unrestricted and unmonitored internet access.", image: UIImage(named: "back"), buttonText: "Next") {() -> Void in
// do something here when users press the button, like ask for location services permissions, register for push notifications, connect to social media, or finish the onboarding process
}
secondPage.movesToNextViewController = true
let thirdPage = OnboardingContentViewController(title: "Terms of Use", body: "You must agree to our Terms of Use to use Submarine.\nIf you don't, please close Submarine.", image: UIImage(named: "back"), buttonText: "View Terms") {() -> Void in
let termsAlert:UIAlertController = UIAlertController(title: "Terms And Conditions", message: "Please view the terms below before accepting them.", preferredStyle: UIAlertControllerStyle.Alert)
termsAlert.addAction(UIAlertAction(title: "View Terms", style: .Default, handler: { (action: UIAlertAction!) in
UIApplication.sharedApplication().openURL(NSURL(string: "my_policy_url")!)
}))
termsAlert.addAction(UIAlertAction(title: "I Agree to the Terms", style: .Default, handler: { (action: UIAlertAction!) in
self.onboardingFinished()
}))
self.presentViewController(termsAlert, animated: true, completion: nil)
// NSNotificationCenter.defaultCenter().postNotificationName("showTermsAlert", object: nil)
}
// Image
let onboardingVC = OnboardingViewController(backgroundImage: UIImage(named: "back"), contents: [secondPage, thirdPage])
self.navigationController?.presentViewController(onboardingVC, animated: false, completion: nil)
}
Обычно 'viewWillDisappear:' метод является хорошим местом для удаления наблюдателей. – Sulthan
@ Султан Может быть, в этом случае, возможно, нет. Я специально не хотел делать конкретные предложения, так как у нас недостаточно информации. Кроме того, как правило, логика 'viewDidAppear:'/'viewWillDisappear:' является ошибкой и часто проблематична, как мы видим здесь. –
@Sulthan so in handleOboarding() Я нажимаю новый VC на NavigationController, а затем в обратном вызове, который возникает после действия пользователя в этом контроллере, я пытаюсь показать предупреждение, вызвав 'showTermsAlert()'. Это немного прояснилось? –