Представление контроллера представления по модулю из делегата листа действия в iOS8 - iOS10
Итак, я заметил, что в iOS8 beta 3 ( Обновление: все еще происходит в iOS 10) на iPad, когда вы пытаетесь представить контроллер вида из метода делегата UIActionSheet
, ничего "происходит, и сообщение журнала выводится на консоль отладки, заявляя, что презентация была предпринята при переходе контроллера предупреждения:
Warning: Attempt to present <UIViewController: 0x...> on <ViewController: 0x...> which is already presenting <UIAlertController: 0x...>
Ответы
Ответ 1
Обновление: В iOS 9 SDK UIActionSheet
устарела, поэтому не ожидайте исправления этой проблемы. Лучше всего использовать UIAlertController
, когда это возможно.
Проблема, похоже, связана с заменой Apple на использование UIAlertController
внутри, чтобы реализовать функциональность представлений предупреждений и листов действий. Эта проблема рассматривается главным образом на iPad и листах действий, поскольку на iPad листы действий представлены как popover в определенном представлении, и то, что 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];
});
Ответ 2
Вы можете попытаться выполнить свою работу (представление контроллера представления) в
- (void) actionSheet:(UIActionSheet *)actionSheet
didDismissWithButtonIndex:(NSInteger)buttonIndex {}
вместо
- (void) actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {}
как сказал @LeoNatan, "Проблема, похоже, связана с заменой Apple на использование внутреннего интерфейса UIAlertController для реализации функциональных возможностей предупреждений и листов действий". Поэтому вы должны подождать, пока лист действия не будет отклонен, а затем представите требуемый контроллер.
Решение @LeoNatan просто блокирует пользовательский интерфейс в основном потоке, поэтому он также будет следить за тем, чтобы контроллер представления был представлен после отклонения листа действия.
Ответ 3
К сожалению, этот код не работает для меня, я думаю, потому что моя проблема не вызывала метод presentController напрямую, а в методе prepareForSegue, поэтому
[segue destinationViewController]
Я заметил, что если segue является "push", все работает правильно, но если он "модальный", просто в ipad, я получил эту ошибку.
Затем я нашел новый вариант в раскадровке на панели segue, и я обошел мою проблему, выбрав "Текущий контекст" для опции "Презентация"
Я надеюсь, что это будет полезно для кого-то другого...
вот скриншот о опции
![enter image description here]()
Ответ 4
У меня была такая же проблема. Я создал отдельное окно для предупреждений и таблиц действий в своем 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];
Ответ 5
Выдача
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
on
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
прежде чем пытаться представить для меня другой режим работы.
Ответ 6
использовать
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
вместо
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
Представление действий представлено выше текущего VC, поэтому это вызывает предупреждение/ошибку.
когда был вызванDismiss, вид действия уже уволен, поэтому никаких проблем вообще:))
Ответ 7
Я установил его в Swift 3 со следующим кодом
DispatchQueue.main.async {
self.present(alertController, animated: true, completion: nil)
}
Ответ 8
Попробуйте
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// action sheet presentation
// or modal view controller presentation
// or alert view presentation
}];
Ответ 9
В 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.