4

Meine Frage ist ziemlich einfach. Ich habe einen UIViewController, der eine UICollectionView enthält. Beim Initialisieren meiner Zellen füge ich jedem einen Gestenerkenner hinzu, so dass beim Antippen und Halten eine Funktion mit einem Selektor aufgerufen wird.Zugriff auf einen übergeordneten UICViewController der UICollectionView

Diese Funktion erstellt dann einen UIAlertController, den ich präsentieren möchte. (Grundsätzlich halten Sie eine Zelle, es fragt Sie, wenn Sie es löschen möchten und wenn Sie ja sagen, es aus der CollectionView entfernt)

Das Problem ist, dass ich einen UIAlertController von meinem UICollectionView nicht präsentieren kann, weil es nicht ist 't ein ViewController.

Ich möchte den UIViewController, der die UICollectionView enthält, programmgesteuert abrufen, um diese Warnung von einer Funktion innerhalb der UICollectionView-Implementierung zu präsentieren.

+0

könnten Sie sich bitte ein Stück Code schreiben?Nur der Code, der die Klasse erstellt und wo Sie die UIAlert erstellen, wird – Eric

+1

Unterklasse der "UICollectionView", um ein "schwach Delegate: UIViewController?" Feld zu halten, und verwenden Sie "CollectionView.delegate = self" aus Ihrem View-Controller. Dann können Sie den Delegierten für die Präsentation verwenden. – sdasdadas

+0

Wenn Sie immer noch nach einer Lösung suchen, habe ich eine Antwort, wo Sie den ersten Eltern-View-Controller für jede Ansicht bekommen können, damit ich es posten kann. –

Antwort

4

ich tun dies, indem ein Protokoll in meiner benutzerdefinierten UICollectionViewCell machen und diese Ereignisse delegieren zurück in die UIViewController, so etwas wie dieses

In Ihrem MyCollectionViewCell

protocol MyCollectionViewCellDelegate: class { 
    func didLongPressCell() 
} 

class MyCollectionViewCell:UICollectionViewCell { 

    weak var delegate:MyCollectionViewCellDelegate? 

    func longPressAction() { 
     if let del = self.delegate { 
      del.didLongPressCell 
     } 
    } 

} 

Dann zurück in Ihre MyViewController

class MyViewController:UIViewController, MyCollectionViewCellDelegate { 

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! MyCollectionViewCell 
     cell.delegate = self 
     return cell 
    } 

    func didLongPressCell() { 
     // do what you want with the event from the cell here 
    } 

} 

Die wichtigen Bits zu erinnern, sind die Delegierten für jede Zelle setzen

cell.delegate = self

Und verabschieden Sie Ihr neues Protokoll im View-Controller, dass Sie die Ereignisse in

class MyViewController:UIViewController, MyCollectionViewCellDelegate

erhalten möchten Ich habe diesen Code nicht getestet und bin mir nicht sicher, ob ich in jeder Zelle Referenzen auf den viewController speichern soll, aber ich mache etwas sehr ähnliches, lassen Sie mich wissen, wie es weitergeht.


Edit: wenn Sie subclassed haben Ihre UICollectionView es dann einen Verweis auf die View-Controller übergeben, so dass Sie es wie so verwenden können.

Ihre MyViewController jetzt wie dieses

class MyViewController:UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     let collectionView = MyCollectionView() 
     collectionView.viewController = self 
     self.view.addSubview(collectionView) 
    } 

} 

Und Ihre individuelle Sammlung Ansicht aussehen würde MyCollectionView

class MyCollectionView:UICollectionView, MyCollectionViewCellDelegate { 

    weak var viewController:UIViewController? 

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! MyCollectionViewCell 
     cell.delegate = self 
     return cell 
    } 

    func didLongPressCell() { 
     if let vc = self.viewController { 
      // make use of the reference to the view controller here 
     } 
    } 

} 

Die UICollectionViewCell wäre das gleiche wie vor

+1

Ich würde den Delegierten schwach machen, um Referenzzyklen zu vermeiden. – nils

+1

@nils Ich habe die Antwort aktualisiert - nur eine schnelle Suche, mein aktuelles Projekt hat 39 Delegierte, die möglicherweise aktualisiert werden müssen: | – Wez

+0

Danke! Das sieht gut aus aber das Problem ist, dass die CellForItemAtIndexPath-Funktion in der UICollectionView und nicht in dem UIViewController aufgerufen wird. Ich verstehe Protokolle nicht wirklich, gibt es eine Möglichkeit, das zu tun, was Sie oben von der UICollectionView zum UIViewController getan haben? –

0

Sie können einfach die RootViewController von UIWindow

guard let delegate = UIApplication.shared.delegate? else { 
    return 
} 
delegate.window.rootViewController.present(yourAlertController, animated:true) 
+0

Das hat nicht für mich funktioniert. Nichts erscheint –

Verwandte Themen