2015-06-06 3 views
15

Eine der Spezifikationen meiner App ist, dass beim Tippen auf eine TableView-Zelle der Benutzer umgeleitet wird auf die mit der Zelle verbundene Website. Hier ist der Code:Swift: Getting 'Snapshot eine Ansicht, die nicht gerendert ..' Fehler beim Versuch, eine URL in Safari aus meiner App zu öffnen

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) 
    } 
} 

Bei meinem ersten Tippen öffnet sich die URL wie es soll. Um jedoch die App von Safari zurückkehren und eine andere Zelle führt zu der folgenden Fehler zu berühren, obwohl nach wie vor die App funktioniert wie es soll:

Snapshot-Erstellung eine Ansicht, die nicht zu einer leeren Schnappschuss gemacht hat. Stellen Sie sicher, dass Ihre Ansicht mindestens einmal gerendert wurde, bevor Sie nach Bildschirmaktualisierungen eine Momentaufnahme oder einen Snapshot erstellen.

Gibt es eine Möglichkeit, diesen Fehler zu vermeiden? Oder ist das ein Fehler?

Ich habe mit dispatch_async Blöcken experimentiert, aber es hat das Problem nicht gelöst.

Antwort

29

Es ist vielleicht nicht das gleiche Problem wie ich, aber ich habe gerade die gleiche Warnung in meinen Protokollen gelöst.

Ich zeige einen UIAlertController als actionSheet popover auf einem ipad, und ich hatte genau die gleiche Warnung 8 Mal hintereinander, jedes Mal wenn ich versuchte, den alarmController zu zeigen.

Um die Warnung verschwinden zu lassen, musste ich nur die alertController Ansicht wie im folgenden Code darstellen.

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

    ...    

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

Ich hoffe, dass dies Ihnen oder einer anderen Person mit der gleichen Warnung hilft.

+0

Ich benutze Objective-C und ich sehe diese Fehler bei der Präsentation eines UIAlertController. Wenn ich eine [alert.view layoutIfNeeded] mache, verschwinden alle Warnungen bis auf eine. Mit anderen Worten, die Wiederholung dieser Warnung endet, aber ich sehe immer noch eine im Protokoll. – Hahnemann

+0

In Swift ab jetzt habe ich keine Warnungen mehr, ich werde versuchen, einige Male zu finden, um es in Objective-C in meiner Freizeit zu testen, ich werde Sie wissen lassen, was ich finde – Saliom

+0

Diese brillante Antwort gelöst meine Problem und löschte ALLE Warnungen. Ich nehme an, Hahnemann hat woanders eine andere Ursache für seine letzte Warnung. – PatrickV

3

Auch unter Verwendung Objective-C, mit der vorgeschlagenen [modeAlert.view layoutIfNeeded] reduziert Fehler auf einen wie oben. Der letzte Fehler wurde durch Ändern der letzten addAction von UIAlertActionStyleCancel zu UIAlertActionStyleDefault wie folgt unterdrückt. Keine große Problemumgehung für einen Fehler.

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

Ich fand, dass das Abbrechen der Option Abbrechen für das iPad-Blatt (es wird sowieso nicht für das iPad angezeigt) den endgültigen Fehler auch los wird. Ich bin immer noch gestört, wenn ich layoutIfNeeded aufrufen muss, aber meine Protokolle sind jetzt sauber. – spstanley

+0

Das Hinzufügen von "layoutIfNeeded()" löschte Fehlermeldungen für mich. Swift: alert.view.layoutIfNeeded() – anorskdev

+5

Auch entdeckt, dass ich layoutIfNeeded() nach presentViewController(), anstatt zuvor - für iPad, aber nicht für das iPhone funktioniert. Putting it nachher gemacht Dinge funktionieren für beide Arten von Geräten. – anorskdev

-1

Ich hatte das gleiche Problem und fand eine einfache Lösung, die Sinn macht.

Wenn es ein iPad ist ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) dann tun NICHT die UIAlertAction mit Stil UIAlertActionStyleCancel zum UIAlertController hinzuzufügen.

Ich machte diese Änderung und meine Fehler gingen weg. Diese Lösung ist sinnvoll, da Sie keine Aktion zum Abbrechen von Alarmen mit Stil UIAlertControllerStyleActionSheet auf einem iPad benötigen.

+0

Es hat keine Wirkung –

+0

Sie haben Recht. Dies löst das Problem nicht immer. Manchmal funktioniert es, manchmal nicht. Ich denke @ Salioms Antwort ist die beste. – nurider

0

Ich trigger eine UIAlertControllerStyleActionSheetUIAlertController, nachdem der Benutzer eine UITableViewRowAction klickt, und ich habe die gleiche Fehlermeldung wiederholt 8 mal nach Vorlage der UIAlertController.

Auf dem iPad Pro Simulator für iOS 9.3, versuchte ich Saliom's answer, und ich ging von acht Protokollmeldungen zu einem.

Als anorskdev suggested, habe ich meinen Ruf zu -[UIView layoutIfNeeded] nach meinem -[UIViewController presentViewController:animated:completion:] Anruf und alle Warnungen verschwunden:

- (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, 
      ]; 
} 

Beachten Sie, dass es nicht notwendig war Patrick's solution von UIAlertActionStyleDefault für cancelAlertAction oder nurider's solution der Beseitigung Verwendung zu verwenden es insgesamt auf iPads.

0

zum Kopieren/Einfügen von Saliom's answer vermeiden Sie es solche Unterklasse und verwenden statt UIAlertController machen können:

class AlertController: UIAlertController { 

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

} 
2

Ich denke, die letzte Warnung der Schaltfläche Abbrechen kam.

Auf iOS8 wird die Abbrechen-Schaltfläche nur bei Bedarf angezeigt. Wenn Sie die App auf dem iPhone ausführen, ist sie sichtbar. Wenn Sie die App auf dem iPad ausführen, wird die Schaltfläche zum Abbrechen nicht angezeigt, und der Handler für die Aktion zum Abbrechen (style: UIAlertActionStyleCancel) wird aufgerufen, wenn der Benutzer außerhalb des Popups tippt.

die Antwort kommen: amalicka's answer

0

Ich war eine ähnliche Debug-Warnung erhalten, wenn ein QLPreviewController modal zu präsentieren versuchen. Ich habe in anderen Posts gelesen, dass es ein Xcode Bug ist.

Für mich wurde der Fehler angezeigt, wenn ich meine App auf dem Simulator lief aber nicht auf einem tatsächlichen Gerät. Muss ein Xcode/Simulator-Problem sein. Ich hoffe, das hilft.

+0

die Antwort, die bereits akzeptiert wird, scheint mir besser. Ihr bietet keine echte Lösung - eine, die den Fehler sowohl am Gerät als auch am Simulator vermeidet. – Alexander

Verwandte Themen