0

Ich habe eine Sammlung Ansicht programmgesteuert, aber wenn collectionView.delegate = self und collectionView.dataSource = self gesetzt Ich bekomme eine Null beim Auspacken ein optionales. Ich weiß nicht, was ich hier falsch gemacht habe.CollectionView Stellvertretung Fehler

class MainFeedViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate, UIViewControllerTransitioningDelegate, UIGestureRecognizerDelegate, MyCollectionCell { 

    let transition = CircularAnimation() 
    var collectionView: UICollectionView! 
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapEdit(recognizer:))) 

    func MyCollectionCell() { 
     let vc = DescriptionViewController() 
     self.present(vc, animated: true, completion: nil) 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     navigationController?.navigationBar.isHidden = true 
     collectionView.delegate = self 
     collectionView.dataSource = self 

     view.backgroundColor = .white 
     UIApplication.shared.isStatusBarHidden = false 
     UIApplication.shared.statusBarStyle = .default 
     view.addSubview(Settings) 
     view.addSubview(topBar) 
     view.addSubview(separatorView) 
     view.addSubview(separatorView2) 

     Settings.translatesAutoresizingMaskIntoConstraints = false 
     Settings.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 15).isActive = true 
     Settings.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
     Settings.widthAnchor.constraint(equalToConstant: 50).isActive = true 
     Settings.heightAnchor.constraint(equalToConstant: 50).isActive = true 

     separatorView.translatesAutoresizingMaskIntoConstraints = false 
     separatorView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40).isActive = true 
     separatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true 
     view.addConstraint(NSLayoutConstraint(item: separatorView, attribute: .left, relatedBy: .equal, toItem: Settings, attribute: .right, multiplier: 1, constant: 15)) 
     view.addConstraint(NSLayoutConstraint(item: separatorView, attribute: .right, relatedBy: .equal, toItem: topBar, attribute: .right, multiplier: 1, constant: 0)) 

     separatorView2.translatesAutoresizingMaskIntoConstraints = false 
     separatorView2.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40).isActive = true 
     separatorView2.heightAnchor.constraint(equalToConstant: 1).isActive = true 
     view.addConstraint(NSLayoutConstraint(item: separatorView2, attribute: .right, relatedBy: .equal, toItem: Settings, attribute: .left, multiplier: 1, constant: -15)) 
     view.addConstraint(NSLayoutConstraint(item: separatorView2, attribute: .left, relatedBy: .equal, toItem: topBar, attribute: .left, multiplier: 1, constant: 0)) 

     topBar.translatesAutoresizingMaskIntoConstraints = false 
     topBar.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 
     topBar.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true 
     topBar.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 
     view.addConstraint(NSLayoutConstraint(item: topBar, attribute: .bottom, relatedBy: .equal, toItem: separatorView, attribute: .top, multiplier: 1, constant: 0)) 
     view.insertSubview(topBar, belowSubview: Settings) 

     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
     let height = (view.frame.width - 16 - 16) * 9/16 
     layout.sectionInset = UIEdgeInsets(top: 80, left: 0, bottom: 0, right: 0) 
     layout.itemSize = CGSize(width: view.frame.width, height: height + 16 + 80) 

     collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout) 
     collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(80, 0, 0, 0) 
     collectionView.dataSource = self 
     collectionView.delegate = self 
     collectionView.register(Cell.self, forCellWithReuseIdentifier: "cellId") 
     collectionView.backgroundColor = UIColor.clear 
     collectionView.addGestureRecognizer(tapGesture) 
     tapGesture.delegate = self 
     self.view.addSubview(collectionView) 
     view.insertSubview(collectionView, belowSubview: topBar) 

    } 

    let Settings : UIButton = { 
     let btn = UIButton() 
     btn.setTitle("Clotho", for: .normal) 
     btn.setTitleColor(.white, for: .normal) 
     btn.layer.cornerRadius = 25 
     btn.backgroundColor = UIColor.rgb(displayP3Red: 255, green: 165, blue: 0) 
     btn.titleLabel?.font = UIFont(name: "Pacifico-Regular", size: 16) 
     btn.addTarget(self, action:#selector(settingsTab), for: .touchUpInside) 
     return btn 
    }() 

    let topBar: UIView = { 
     let bar = UIView() 
     bar.backgroundColor = .white 
     return bar 
    }() 

    let separatorView: UIView = { 
     let view = UIView() 
     view.backgroundColor = UIColor.rgb(displayP3Red: 211, green: 211, blue: 211) 
     return view 
    }() 

    let separatorView2: UIView = { 
     let view2 = UIView() 
     view2.backgroundColor = UIColor.rgb(displayP3Red: 211, green: 211, blue: 211) 
     return view2 
    }() 

    @objc func tapEdit(recognizer: UITapGestureRecognizer) { 
     if recognizer.state == UIGestureRecognizerState.ended { 
      let tapLocation = recognizer.location(in: self.collectionView) 
      if let tapIndexPath = self.collectionView.indexPathForItem(at: tapLocation) { 
       if (self.collectionView.cellForItem(at: tapIndexPath) as? Cell) != nil { 
        //do what you want to cell here 

       } 
      } 
     } 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 4 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! Cell 
     cell.Delegate = self 
     return cell 
    } 

    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     transition.transitionMode = .present 
     transition.startingPoint = Settings.center 
     transition.circleColor = Settings.backgroundColor! 

     return transition 
    } 

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     transition.transitionMode = .dismiss 
     transition.startingPoint = Settings.center 
     transition.circleColor = Settings.backgroundColor! 

     return transition 
    } 

    @objc func settingsTab(){ 
     let secondVC = SettingsViewController() 
     secondVC.transitioningDelegate = self 
     secondVC.modalPresentationStyle = UIModalPresentationStyle.custom 
     self.present(secondVC, animated: true, completion: nil) 
    } 
} 

stelle ich eine var Delegate: MyCollectionCell? in meiner Zelle mit einem

 import UIKit 

     protocol MyCollectionCell { 
      func MyCollectionCell() 
     } 

     class Cell: UICollectionViewCell { 

      var Delegate: MyCollectionCell? 

      override init(frame: CGRect) { 
       super.init(frame: frame) 
       setupViews() 

       let TapGesture = UITapGestureRecognizer(target: self, action: #selector(Cell.tapEdit(sender:))) 
       addGestureRecognizer(TapGesture) 
       TapGesture.delegate = MainFeedViewController() 
      } 
    //other setup code... 

@objc func tapEdit(sender: UITapGestureRecognizer) { 
     Delegate?.MyCollectionCell() 
    } 

Antwort

0

Sie haben nicht wirklich die Sammlung Sicht überall geschaffen.

Diese Zeile:

var collectionView: UICollectionView! 

schafft eine Variable bereit, die Sammlung Ansicht (und das Zeichen gibt Sie die Variable in der viewDidLoad Methode bevölkern sollen!) Zu halten, aber Sie schaffen nicht wirklich die Instanz von der UICollectionView und weisen Sie es dieser Variablen zu.

Wenn Sie also versuchen, den Delegaten und die Datenquelle festzulegen, ist die Sammlungsansichtsvariable immer noch gleich Null, und Sie erhalten einen Fehler.

Sie müssen tatsächlich die Instanz einer UICollectionView erstellen, die auch die Erstellung einer Instanz einer UICollectionViewLayout (oder einer Unterklasse davon wie UICollectionViewFlowLayout) umfasst.

Auf der grundlegendsten Ebene, die Sie so etwas tun sollte:

let layout = UICollectionViewFlowLayout() 
layout.itemSize = CGSize(width: 100, height: 100) 
collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 500, height: 500), collectionViewLayout: layout) 

obwohl natürlich sollten Sie den Rahmen und die Parameter des Layouts passen Sie Ihre Nutzungsanforderungen gerecht zu werden.

+0

ja ich habe bereits das nur anders formatiert es ist am unteren 'viewDidLoad' –

+0

Das ist das Problem obwohl. Es kann nicht sein, nachdem Sie versuchen, es zu verweisen. Sie müssen das tun, bevor Sie versuchen, es zu verwenden. Also sollte es irgendwo ganz oben gehen. Es ist keine Frage der Formatierung, dass Sie die Instanz der UICollectionView erstellen müssen, bevor Sie versuchen, auf sie zuzugreifen. Die Reihenfolge ist kritisch. Es ist, als ob man versucht, die Tür eines Taxis zu öffnen, bevor das Taxi ankommt, man kann es nicht tun, selbst wenn man weiß, dass das Taxi ankommen wird. –

Verwandte Themen