2015-06-06 20 views
15

Una delle specifiche della mia app è che quando si tocca una cella TableView, l'utente verrà reindirizzato al sito Web associato alla cella. Ecco il codice:Swift: quando si tenta di aprire un URL in Safari dalla mia app, viene visualizzato un errore quando si tenta di aprire un URL dalla mia app

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

Al mio primo tocco, l'URL si apre come previsto. Tuttavia, tornando alla applicazione da Safari e toccare un altro risultato di cellule nel seguente errore, anche se l'applicazione funziona ancora come si suppone:

snapshotting una vista che non è stato reso risultati in un snapshot vuoto. Assicurati che la tua vista sia stata renderizzata almeno una volta prima dello snapshot o dello snapshot dopo gli aggiornamenti dello schermo.

C'è un modo per evitare questo errore? O questo è un bug?

Ho sperimentato con i blocchi dispatch_async ma non ha risolto il problema.

risposta

29

Potrebbe non essere lo stesso problema di me, ma ho appena risolto lo stesso avviso nei miei registri.

Sto mostrando un UIAlertController come un popover del foglio di azione su un ipad, e ho avuto esattamente lo stesso avviso 8 volte di seguito ogni volta che ho provato a mostrare l'alertController.

Per rendere l'avviso scomparire tutto quello che dovevo fare era impostare la vista alertController come nel seguente codice.

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

    ...    

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

Spero che questo aiuti voi o qualsiasi altra persona che ha lo stesso avvertimento.

+0

Sto usando Objective-C e vedo questi errori quando si presenta un UIAlertController. Se faccio un [alert.view layoutIfNeeded] tutti gli avvertimenti vanno via tranne uno. In altre parole, la ripetizione di questo avviso termina ma ne vedo ancora uno nel registro. – Hahnemann

+0

In Swift come ora non ho più alcun avvertimento, cercherò di trovare qualche volta per testarlo in Objective-C nel mio tempo libero, ti farò sapere cosa trovo – Saliom

+0

Questa brillante risposta ha risolto il mio problema e rimosso TUTTI gli avvertimenti. Quindi immagino che Hahnemann abbia un'altra causa da qualche altra parte per il suo ultimo avvertimento. – PatrickV

3

Anche utilizzando Objective-C, utilizzando gli errori ridotti [modeAlert.view layoutIfNeeded] suggeriti su uno come sopra. L'errore finale è stato soppresso modificando l'ultima addAction da UIAlertActionStyleCancel a UIAlertActionStyleDefault come di seguito. Non una soluzione eccezionale per quello che sembra essere un bug.

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

Ho scoperto che lasciare l'opzione Annulla per il foglio iPad (non viene comunque mostrato per l'iPad) elimina anche l'errore finale. Sono ancora infastidito dal dover chiamare layoutIfNeeded, ma i miei registri ora sono puliti. – spstanley

+0

L'aggiunta di "layoutIfNeeded()" ha eliminato i messaggi di errore per me. Swift: alert.view.layoutIfNeeded() – anorskdev

+5

Inoltre ho scoperto che dovevo fare layoutIfNeeded() DOPO presentViewController(), piuttosto che prima - prima sembrava funzionare per iPad, ma non per iPhone. Metterlo dopo aver fatto funzionare le cose per entrambi i tipi di dispositivi. – anorskdev

-1

Ho avuto lo stesso problema e ho trovato una soluzione semplice che ha senso.

Se si tratta di un iPad ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) poi fare NON aggiungere il UIAlertAction con stile UIAlertActionStyleCancel al UIAlertController.

Ho apportato questa modifica e i miei errori sono andati via. Questa soluzione ha senso poiché non è necessario annullare un'azione per gli avvisi con lo stile UIAlertControllerStyleActionSheet su un iPad.

+0

Non ha effetto –

+0

Hai ragione. Questo non risolve sempre il problema. A volte funziona, a volte no. Penso che la risposta di @ Saliom sia la migliore. – nurider

0

Sto attivando uno UIAlertControllerStyleActionSheetUIAlertController dopo che l'utente fa clic su UITableViewRowAction e ho ricevuto lo stesso messaggio di errore ripetuto 8 volte dopo aver presentato lo UIAlertController.

Sull'iPad Pro Simulator per iOS 9.3, ho provato Saliom's answer e sono passato da otto messaggi di registro a uno.

Come anorskdev suggested, ho messo la mia chiamata al -[UIView layoutIfNeeded] dopo la mia -[UIViewController presentViewController:animated:completion:] chiamata, e tutti gli avvertimenti scomparsi:

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

Si noti che non è stato necessario usare Patrick's solution di utilizzare UIAlertActionStyleDefault per cancelAlertAction o nurider's solution di eliminare tutto su iPad.

0

Per evitare di copia/incolla da Saliom's answer è possibile effettuare tale sottoclasse e utilizzarlo al posto di UIAlertController:

class AlertController: UIAlertController { 

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

} 
2

penso che l'ultimo avvertimento è venuto dal pulsante Annulla.

Su iOS8 il pulsante Annulla viene visualizzato solo quando necessario. Se si esegue l'app su iPhone è visibile. Se si esegue l'applicazione su iPad, il pulsante Annulla non viene visualizzato e il gestore per l'azione Annulla (stile: UIAlertActionStyleCancel) viene chiamato quando l'utente tocca fuori dal popup.

la risposta provengono da: amalicka's answer

0

mi è stato sempre un avvertimento di debug simile quando si cerca di presentare un QLPreviewController modale. Ho letto su altri post che si tratta di un bug Xcode.

Per me l'errore visualizzato quando ho eseguito la mia app sul simulatore ma non su un dispositivo reale. Deve essere un problema Xcode/Simulator. Spero possa aiutare.

+0

la risposta che è già accettata mi sembra migliore. La tua non fornisce una soluzione reale - quella che evita l'errore sia sul dispositivo che sul simulatore. – Alexander

Problemi correlati