2015-05-27 13 views
9

Sto tentando di aggiungere avvisi a una UITableViewCell personalizzata per presentare un UIAlertView Ho bisogno di chiamare presentViewController da UIViewController. Tuttavia, non sono a conoscenza di come accedere all'istanza UIViewController corrente dalla classe UITableViewCell. Il codice seguente è il mio tentativo di farlo con un'estensione.Presentazione di UIAlertController da UITableViewCell

ottengo questo errore

Espressione deliberato la funzione di inutilizzata.

extension UIViewController 
{ 

    class func alertReminden(timeInterval: Int) 
    { 
     var refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertControllerStyle.Alert) 

     refreshAlert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action: UIAlertAction!) in 
      Alarm.createReminder("Catch the Bus", 
       timeInterval: NSDate(timeIntervalSinceNow: Double(timeInterval * 60))) 
     })) 

     refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in 
      println("Handle Cancel Logic here") 
     })) 

     UIViewController.presentViewController(refreshAlert) 


    } 
} 

class CustomRouteViewCell: UITableViewCell { 

risposta

24

È possibile utilizzare questa estensione per trovare la viewController che presentano la cellula

extension UIView { 
var parentViewController: UIViewController? { 
    var parentResponder: UIResponder? = self 
    while parentResponder != nil { 
     parentResponder = parentResponder!.nextResponder() 
     if parentResponder is UIViewController { 
      return parentResponder as! UIViewController! 
     } 
    } 
    return nil 
} 
} 

o utilizzare rootViewController di presentare:

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(refreshAlert, animated: true, completion: nil)

11

provare a sostituire a questa riga di codice:

Swift 2

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(refreshAlert, animated: true, completion: nil) 

Swift 3

UIApplication.shared.keyWindow?.rootViewController?.present(refreshAlert, animated: true, completion: nil) 
+0

wow super hack genio ragazzo! – mattyU

+0

Grazie amici per il tuo fantastico lavoro. – Jaydip

+0

Questo non ha funzionato da quando il mio tableview era anche in un controller di navigazione. Sono stato in grado di presentare utilizzando se lasciato topController = UIApplication.topViewController() { topController.present (alertController, animato: true, completion: nil) } – DoesData

9

Un altro modo per farlo è quello di dichiarare un protocollo e una proprietà delegato nella classe di celle della vista tabella, impostare il controller come delegato delle celle e implementare il protocollo nel controller che è in grado di presentare il controller della vista di avviso.

+1

Penso che questo approccio sia il più pulito. – jrf

+0

Ma se si desidera manipolare alcuni controlli all'interno della tableviewcell dopo che l'avviso è stato eliminato, non si avrà accesso ad essi –

7

La soluzione di Leo ha funzionato per me. L'ho usato per presentare un AlertView da una cella di visualizzazione raccolta personalizzata.

Aggiornamento per Swift 3.0:

extension UIView { 
    var parentViewController: UIViewController? { 
     var parentResponder: UIResponder? = self 
     while parentResponder != nil { 
      parentResponder = parentResponder!.next 
      if parentResponder is UIViewController { 
       return parentResponder as! UIViewController! 
      } 
     } 
     return nil 
    } 
} 

Speranza che aiuta.

+1

Eccellente !!! questo funziona benissimo ... – Annjawn

+0

funziona davvero bene –

0

Si potrebbe provare a utilizzare un protocollo e delegare, utilizzando questo metodo si avrà la possibilità di presentare non solo gli avvisi, ma potrebbe fornire una migliore interazione con il proprio controller di visualizzazione nel caso in cui ne aveste bisogno in futuro. Per esempio:

protocol alerts: class{ 

    func presentAlert(title:String, message:String) 

} 

Poi, nel tuo tableViewCell si creerà qualcosa di simile:

var alertsDelegate : alerts? 

//And whenever you need to present a message call something inside the cell like: 

alertsDelegate?.presentAlert(title:"Your title", message:"Your message") 

Poi, nel tuo viewController, in primo luogo impostare il vostro viewController come avvisi

class yourClassName : ViewController, alerts { 

    //And add the functions of the protocol 
    func presentAlert(title:String, message:String){ 
     //This is the function that'll be called from the cell 
     //Here you can personalize how the alert will be displayed 

    } 
} 

In secondo luogo, impostare il delegato per la cella nel metodo "cellForRowAt"

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCell(withIdentifier: "yourIdentifier") as! yourCellClass 

    cell.alertsDelegate = self 

} 

E proprio così è possibile creare più funzioni che adattano le vostre esigenze in relazione alla comunicazione con viewController o viewControllers.

Problemi correlati