CollectionView委托错误

时间:2017-12-29 22:46:59

标签: swift uicollectionview protocols uigesturerecognizer uicollectionviewcell

我已经以编程方式创建了一个集合视图但是在设置collectionView.delegate = selfcollectionView.dataSource = self时,我在打开一个可选项时得到一个nil。我不知道我在这里做错了什么。

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

我在我的单元格中设置var Delegate: MyCollectionCell? protocol

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

1 个答案:

答案 0 :(得分:0)

您实际上并未在任何地方创建过集合视图。

这一行:

var collectionView: UICollectionView!

创建一个准备保存集合视图的变量(并且!字符表示您应该在viewDidLoad方法中填充变量),但实际上并没有创建UICollectionView的实例并将其分配给该变量。

因此,当您尝试设置委托和数据源时,集合视图变量仍为零,因此您会收到错误。

您需要实际创建UICollectionView的实例,该实例还将涉及创建UICollectionViewLayout的实例(或其子类,如UICollectionViewFlowLayout)。

在最基本的层面上,你应该做这样的事情:

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

虽然您当然应该调整框架和布局参数以满足您的使用要求。