Подтвердить что ты не робот

Представление контроллера представления по модулю из делегата листа действия в iOS8 - iOS10

Итак, я заметил, что в iOS8 beta 3 ( Обновление: все еще происходит в iOS 10) на iPad, когда вы пытаетесь представить контроллер вида из метода делегата UIActionSheet, ничего "происходит, и сообщение журнала выводится на консоль отладки, заявляя, что презентация была предпринята при переходе контроллера предупреждения:

Warning: Attempt to present <UIViewController: 0x...> on <ViewController: 0x...> which is already presenting <UIAlertController: 0x...>
4b9b3361

Ответ 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.