Swift: получение "Снимок снимка, который не был обработан.." при попытке открыть URL-адрес в сафари из моего приложения

Одна из спецификаций моего приложения заключается в том, что при нажатии на ячейку tableView пользователь будет перенаправлен на веб-сайт, связанный с ячейкой. Вот код:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if let url = NSURL(string: appdelegate.studentInfo[indexPath.row].url) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        UIApplication.sharedApplication().openURL(url)
    }
    else {
        let alert = UIAlertController(title: "Invalid URL", message: "Cannot open URL because it is invalid.", preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Cancel, handler: nil))
        self.presentViewController(alert, animated: true, completion: nil)
    } 
}

При первом нажатии URL открывается, как и предполагалось. Однако возврат к приложению из Safari и касание другой ячейки приводит к следующей ошибке, хотя приложение все еще работает так, как предполагается:

Снимок снимка, который не был отображен, приводит к пустой снимок. Убедитесь, что ваше представление было просмотрено не ранее, чем раньше моментальный снимок или моментальный снимок после обновления экрана.

Есть ли способ избежать этой ошибки? Или это ошибка?

Я экспериментировал с блоками dispatch_async, но это не решило проблему.

Ответы

Ответ 1

Это может быть не такая же проблема, как у меня, но я просто решил одно и то же предупреждение в своих журналах.

Я показываю UIAlertController как всплывающее окно actionSheet на ipad, и я имел точно такое же предупреждение 8 раз подряд каждый раз, когда я пытался показать alertController.

Чтобы исчезнуть предупреждение, все, что мне нужно было сделать, - это разметка вида alertController, как в следующем коде.

    let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)

    ...            

    alertController.view.layoutIfNeeded() //avoid Snapshotting error
    self.presentViewController(alertController, animated: true, completion: nil)

Надеюсь, это поможет вам или любому другому человеку, имеющему такое же предупреждение.

Ответ 2

Также используя Objective-C, используя предлагаемые [modeAlert.view layoutIfNeeded] приведенные ошибки к одному, как указано выше. Окончательная ошибка была подавлена ​​путем изменения последнего addAction от UIAlertActionStyleCancel до UIAlertActionStyleDefault, как показано ниже. Не большой обходной путь к тому, что кажется ошибкой.

[modeAlert addAction:[UIAlertAction
                  actionWithTitle:NSLocalizedString(@"Cancel", @"")
                  style:UIAlertActionStyleDefault
                  handler:nil ]];

Ответ 3

Я думаю, что последнее предупреждение появилось с помощью кнопки "Отмена".

В iOS8 кнопка отмены отображается только при необходимости. Если вы запустите приложение на iPhone, оно будет видно. Если вы запустите приложение на iPad, кнопка отмены не отображается, а обработчик для действия отмены (стиль: UIAlertActionStyleCancel) вызывается, когда пользователь выходит за пределы всплывающего окна.

ответ исходит из: ответ амалики

Ответ 4

Я запускаю UIAlertControllerStyleActionSheet UIAlertController после того, как пользователь нажимает кнопку UITableViewRowAction, и я получил то же сообщение об ошибке, повторяющееся 8 раз после представления UIAlertController.

На iPad Pro Simulator для iOS 9.3 я попробовал ответ Saliom, и я перешел от восьми сообщений журнала к одному.

Как anorskdev предложил, я поместил свой вызов -[UIView layoutIfNeeded] после моего вызова -[UIViewController presentViewController:animated:completion:], и все предупреждения исчезли:

- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
  UITableViewRowAction *moreAction =
  [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault
                                     title:@"More"
                                   handler:^(UITableViewRowAction * _Nonnull action,
                                             NSIndexPath * _Nonnull moreIndexPath)
  {
    UIAlertController *alertController = 
    [UIAlertController alertControllerWithTitle:name 
                                        message:nil
                                 preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *deleteAlertAction = 
    [UIAlertAction actionWithTitle:@"Delete"
                             style:UIAlertActionStyleDestructive
                           handler:deleteAction];
    [alertController addAction:deleteAlertAction];

    UIAlertAction *cancelAlertAction = 
    [UIAlertAction actionWithTitle:@"Cancel"
                             // totally ok to use the proper
                             // UIAlertActionStyleCancel
                             style:UIAlertActionStyleCancel
                           handler:cancelAction];
    [alertController addAction:cancelAlertAction];

    CGRect sourceRect = [self.tableView rectForRowAtIndexPath:moreIndexPath];

    // You must specify a sourceRect and sourceView
    // or a barButtonItem or presenting a
    // UIAlertControllerStyleActionSheet UIAlertController
    // will crash on iPad.
    alertController.popoverPresentationController.sourceRect = sourceRect;
    alertController.popoverPresentationController.sourceView = self.tableView;
    // first, present the alertController
    [self presentViewController:alertController
                       animated:YES
                     completion:nil];
    // then -layoutIfNeeded
    [alertController.view layoutIfNeeded];
  }
  return @[
          moreAction,
          ];
}

Обратите внимание, что нет необходимости использовать решение Patrick с использованием UIAlertActionStyleDefault для cancelAlertAction или решения nurider полностью исключить его на iPad.

Ответ 5

Чтобы избежать копирования/вставки из ответа Saliom, вы можете сделать такой подкласс и использовать его вместо UIAlertController:

class AlertController: UIAlertController {

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        self.view.layoutIfNeeded()
    }

}

Ответ 6

Я получал аналогичное предупреждение об отладке при попытке представить QLPreviewController модально. Я читал на других сообщениях, что это ошибка Xcode.

Для меня ошибка отображается при запуске моего приложения на симуляторе, но не на самом устройстве. Должна быть проблема с Xcode/Simulator. Надеюсь, что это поможет.

Ответ 7

У меня была та же проблема, и я нашел простое решение, которое имеет смысл.

Если это iPad ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad), тогда НЕ добавьте UIAlertAction со стилем UIAlertActionStyleCancel в UIAlertController.

Я сделал это изменение, и мои ошибки исчезли. Это решение имеет смысл, так как вам не требуется действие отмены для предупреждений со стилем UIAlertControllerStyleActionSheet на iPad.