1

J'ai un bouton dans mon UICollectionViewCell.swift: Je veux, en fonction de certains paramètres, être capable de présenter une alerte.Présenter AlertView depuis UICollectionViewCell

class CollectionViewCell: UICollectionViewCell { 
    var collectionView: CollectionView! 

@IBAction func buttonPressed(sender: UIButton) { 

    doThisOrThat() 
} 


func doThisOrThat() { 
    if x == .NotDetermined { 
     y.doSomething() 
    } else if x == .Denied || x == .Restricted { 
      showAlert("Error", theMessage: "there's an error here") 
      return 
     } 
    } 

func showAlert(title: String, theMessage: String) { 
    let alert = UIAlertController(title: title, message: theMessage, preferredStyle: UIAlertControllerStyle.Alert) 
    alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)) 
    self.collectionView!.presentViewController(alert, animated: true, completion: nil) 
} 

Sur la ligne self.collectionView!.presentViewController je reçois une pause:

fatal error: unexpectedly found nil while unwrapping an Optional value

Je devine que cela a someting à voir avec la façon dont CollectionView est utilisé - Je ne comprends pas tout à fait encore optionals . Je sais qu'un UICollectionCell ne peut pas .presentViewController - c'est pourquoi j'essaye d'obtenir UICOllectionView pour le faire.

Comment est-ce que je fais ce travail? J'ai pensé à utiliser un extension mais je ne sais pas comment faire UICOllectionViewCell adopter .presentViewController

Des idées?

Répondre

2

La cellule de vue de collection ne doit pas dépendre de la connaissance de sa vue parente ou de son contrôleur de vue afin de maintenir une séparation fonctionnelle des responsabilités qui fait partie d'une architecture d'application appropriée. Par conséquent, pour que la cellule adopte le comportement consistant à afficher une alerte, le modèle de délégation peut être utilisé. Ceci est fait en ajoutant un protocole au contrôleur de vue qui a la vue de collection.

@protocol CollectionViewCellDelegate: class {  
    func showAlert()  
} 

et ayant le contrôleur de vue conforme à ce protocole:

class MyViewController: UIViewController, CollectionViewCellDelegate { 

ajouter également une propriété déléguée à la cellule:

weak var delegate: CollectionViewCellDelegate? 

Déplacer la fonction showAlert() dans votre contrôleur de vue de la collecte.

Lorsque vous créez une cellule, affectez le délégué de la cellule au contrôleur de vue de collection.

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 

    // Other cell code here. 

    cell.delegate = self 

Quand il est temps de montrer l'alerte, la conférence téléphonique cellulaire

delegate.showAlert() 

L'alerte sera alors présenté sur le contrôleur de vue de collection parce qu'il a été défini comme le délégué de la vue de collection cellule.

+0

salut Z @ Daniel - merci pour votre explication. J'ai ajouté '@protocol ...' directement sous l'instruction 'import' de' CollectionView'. Puis j'ai ajouté le 'CollectionViewDelegate' à la classe' CollectionViewCell' ... ajouté la propriété de délégué à 'CollectionViewCell' (ne me permettrait pas de le rendre faible). Déplacé 'showAlert' au contrôleur de vue. Délégué assigné dans 'cellForItem', et appelé l'alerte dans la cellule avec le' delegate' ... – SamYoungNY

+0

Je reçois une erreur "Tapez 'CollectionViewCell' n'est pas conforme au protocole CollectionViewDelegate" l'ouverture de cette option indique ... "Le protocole requiert la fonction 'showAert (0' avec le type '() ->()' ... – SamYoungNY

+0

Quelques corrections à ma réponse Le protocole doit avoir l'annotation de classe pour que la propriété delegate soit faible, et votre contrôleur de vue sera conforme au protocole fournissant ainsi la fonctionnalité showAlert que la cellule utilisera. d'avoir la cellule conforme au protocole. – Daniel

0

Avec moi, il arrive une petite différence dans la méthode actuelle:

self.window?.rootViewController?.present(alert, animated: true, completion: nil)