Is there a way to use UICollectionView Programmatically with AutoLayout ?

I'm trying to create a UICollectionView programmatically with AutoLayout and I have some issues.


First Test:

In my first try I created a UICollectionView as a Lazy var and added it in the viewDidLoad like this:


lazy var collection: UICollectionView = {
        let cv = UICollectionView()
        cv.translatesAutoresizingMaskIntoConstraints = false
  cv.setCollectionViewLayout(self.flowLayout, animated: true)
        cv.dataSource = self
        cv.delegate = self
        cv.registerClass(MyViewCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(self.collection)
       //Constraints was here..
  }


This approuch took me to this error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'


Second Test:


So I had to use the frame/collectionViewLayout initializer and my second try looked like this:


lazy var collection: UICollectionView = {
        let cv = UICollectionView(frame: UIScreen.mainScreen().bounds, collectionViewLayout: self.flowLayout)
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.setCollectionViewLayout(self.flowLayout, animated: true)
        cv.dataSource = self
        cv.delegate = self
        cv.registerClass(MenuViewCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(self.collection)

        //Constraints was here..
  }


with this approuch I got a blank screen, using debugger I found out that the datasource delegate methods was called (numberOfItemsInSection and numberOfSectionsInCollectionView), but no other delegate methods was called (sizeForItemAtIndexPath and cellForItemAtIndexPath)


So I decided to get rid of autoLayout and see the way things work.


Third Test:


lazy var collection: UICollectionView = {
        let cv = UICollectionView(frame: UIScreen.mainScreen().bounds, collectionViewLayout: self.flowLayout)
      //  cv.translatesAutoresizingMaskIntoConstraints = false
        cv.setCollectionViewLayout(self.flowLayout, animated: true)
        cv.dataSource = self
        cv.delegate = self
        cv.registerClass(MenuViewCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    }()
  
  
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(self.collection)

  //No more constraints here !!!
  }


And everything worked fine.


So, my question is : Is there a way to use UICollectionView Programmatically with AutoLayout ?

Sure. I suspect the problem was in your constraints (the "constraints was here" [sic] that you edited out).


What is the frame of your collection view at runtime after layout? You can print it out in viewDidLayoutSubviews to check.

Accepted Answer

我是这样用的,没发现有什么问题。希望下面的代码对你有所帮助。



        let gridView = UICollectionView(frame: CGRectZero, collectionViewLayout: layout)
        gridView.translatesAutoresizingMaskIntoConstraints = false
        gridView.showsVerticalScrollIndicator = false
        gridView.registerClass(GoodsItem.classForCoder(), forCellWithReuseIdentifier:controller.cellId)
        gridView.dataSource = controller
        gridView.delegate = controller
     
        addSubview(gridView)
     
        let views = ["titleBar":titleBar,"gridView":gridView]
     
        var constraints =  NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[titleBar]-0-|", options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: views)
        addConstraints(constraints);
     
        constraints =  NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[gridView]-0-|", options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: views)
        addConstraints(constraints);
     
        constraints =  NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[titleBar(60)]-0-[gridView]-0-|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views)
        addConstraints(constraints);

Thanks for the tip !

Is there a way to use UICollectionView Programmatically with AutoLayout ?
 
 
Q