Представление контроллера вида модально из делегата листа действий в iOS8 - iOS11
поэтому я заметил, что в iOS8 beta 3 (обновление: все еще происходит в iOS 11.2) на iPad, при попытке представить контроллер представления из метода делегата a UIActionSheet," ничего " не происходит, и на консоль отладки выводится сообщение журнала, в котором говорится, что презентация была предпринята при переходе на контроллер предупреждений:
Warning: Attempt to present <UIViewController: 0x...> on <ViewController: 0x...> which is already presenting <UIAlertController: 0x...>
9 ответов:
обновление: начиная с iOS 9 SDK,
UIActionSheetявляется устаревшим, поэтому не ожидайте исправления этой проблемы. Лучше всего начать использоватьUIAlertControllerкогда это возможно.
проблема, похоже, исходит от переключения Apple на использование
UIAlertControllerвнутренне для реализации функциональности представлений предупреждений и листов действий. Проблема видна в основном на iPad и листах действий, потому что на iPad листы действий представлены как всплывающее окно в указанном представлении, и то, что делает Apple путешествуйте по цепочке ответчика, пока он не найдет контроллер вида и не вызоветpresentViewController:animated:completion:внутренниеUIAlertController. Проблема менее очевидна на iPhone и с предупреждающими видами, потому что там Apple фактически создает отдельное окно, пустой контроллер вида и представляет внутреннийUIAlertControllerкроме того, так что это, кажется, не мешает другой презентации.Я открыл отчет об ошибке для этого вопроса: rdar://17742017. Пожалуйста, продублируйте его и дайте Apple знать, что это проблема.
в качестве обходного пути я рекомендую отложить презентацию до следующего runloop, используя следующий метод:
dispatch_async(dispatch_get_main_queue(), ^ { [self presentViewController:vc animated:YES completion:nil]; });
вы можете попробовать сделать свою работу (представление контроллера вида) в
- (void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {}вместо
- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {}как сказал @LeoNatan, "проблема, похоже, исходит от переключения Apple на использование UIAlertController внутри для реализации функциональности представлений предупреждений и листов действий". Поэтому вы должны дождаться, когда лист действий будет отклонен, а затем представить контроллер вида, который вы хотите.
решение @ LeoNatan просто блокирует пользовательский интерфейс в главном потоке, поэтому он также будет убедитесь, что контроллер вида будет представлен после того, как лист действий был отклонен.
к сожалению, этот код не работает для меня, я думаю, потому что моя проблема не вызывала метод presentController напрямую, а в методе prepareForSegue, поэтому используя
[segue destinationViewController]Я заметил, что если segue "push" вид все работает правильно, но если это "модальный", только в ipad, я получил эту ошибку.
затем я нашел новую опцию в раскадровке на панели segue, и я решил свою проблему, выбрав "текущий контекст" для презентации вариант
Я надеюсь, это будет полезно для кого-то другого... вот скриншот о опции
у меня была такая же проблема. Я создал отдельное окно для предупреждений и таблиц действий в моем appdelegate и представил предупреждения на нем. Это сработало для меня!
self.alertWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.alertWindow.backgroundColor = [UIColor clearColor]; UIViewController *dummy = [[UIViewController alloc] init]; [self.alertWindow setRootViewController:dummy];Вы можете представить как :
[[myAppDelegate appDelegate].alertWindow makeKeyAndVisible]; [[myAppDelegate appDelegate].alertWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
я исправил это в Swift 3 со следующим кодом
DispatchQueue.main.async { self.present(alertController, animated: true, completion: nil) }
выдает
[self.navigationController dismissViewControllerAnimated:YES completion:nil];on
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndexпрежде чем пытаться представить другой модальный работал для меня.
использовать
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndexвместо
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndexвид действия представлен выше текущего VC, так что это то, что вызывает предупреждение/ошибку. когда diddismiss называется, вид действия уже отклонен, так что никаких проблем вообще :))
попробовать
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ // action sheet presentation // or modal view controller presentation // or alert view presentation }];
В iOS 8 Apple использует UIAlertController внутренне для реализации функциональности представлений предупреждений и листов действий. Поэтому, когда вы хотите показать UIViewController модально после отображения UIActionSheet или UIAlertView в методе делегата, например
(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndexи
(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndexвы должны сначала уволить UIAlertController следующим образом:
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) { UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; [vc dismissViewControllerAnimated:NO completion:^{ }]; }Теперь вы можете представить модальный UIViewController в iOS 8.
