使用AutoLayout编程创建一个UICollectionView

5
我想编写一个使用AutoLayout创建UICollectionView的程序,但遇到了一些问题。 第一次尝试: 我首先创建了一个懒加载的UICollectionView,并在viewDidLoad中添加了它,如下所示:
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)
}

这种方法导致了以下错误:

应用程序终止,原因是未捕获的异常 'NSInvalidArgumentException',原因:'UICollectionView必须使用非空布局参数初始化'

第二个测试:

因此,我不得不使用frame/collectionViewLayout初始化器,我的第二次尝试如下:

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 there...

}

使用这种方法后,我得到了一个空白屏幕。使用调试器发现数据源委托方法被调用(numberOfItemsInSectionnumberOfSectionsInCollectionView),但没有其他委托方法被调用(sizeForItemAtIndexPathcellForItemAtIndexPath)。

因此,我决定摆脱自动布局并查看事情的运作方式。

第三个测试:

 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 !!!

}

一切都运作正常。

因此,我的问题是:是否有一种方法可以使用自动布局来编程使用UICollectionView?

解决方案

过了一段时间,我发现我的问题在于约束条件。然后我想出了这个解决方案:

 let slice = (UIScreen.mainScreen().bounds.height / CGFloat(3.0)) 

    lazy var flowLayout:UICollectionViewFlowLayout = {
        let f = UICollectionViewFlowLayout()
        f.scrollDirection = UICollectionViewScrollDirection.Horizontal
        return f
    }()


    lazy var collection: UICollectionView = {
        let cv = UICollectionView(frame: CGRectZero, 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)

        let views = ["collection":self.collection]

        var constraints =  NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[collection]-0-|", options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: views)
        self.view.addConstraints(constraints)

        constraints =  NSLayoutConstraint.constraintsWithVisualFormat("V:|-\(slice)-[collection]-\(slice)-|", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views)
        self.view.addConstraints(constraints)
    }

太棒了,非常感谢。 - Mohamed Saleh
很感激你提到了 @hellogoogle 的解决方案 https://developer.apple.com/forums/thread/26510 ;) - AdPiscinam
1个回答

6

过了一会儿,我发现问题出在限制条件上。然后我想出了以下解决方案:

 let slice = (UIScreen.mainScreen().bounds.height / CGFloat(3.0)) 

    lazy var flowLayout:UICollectionViewFlowLayout = {
        let f = UICollectionViewFlowLayout()
        f.scrollDirection = UICollectionViewScrollDirection.Horizontal
        return f
    }()


    lazy var collection: UICollectionView = {
        let cv = UICollectionView(frame: CGRectZero, 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)

        let views = ["collection":self.collection]

        var constraints =  NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[collection]-0-|", options: NSLayoutFormatOptions.AlignAllTop, metrics: nil, views: views)
        self.view.addConstraints(constraints)

        let stringConstraint = "V:|-\(slice)-[collection]-\(slice)-|"

        print("stringConstraint: \(stringConstraint)")

        constraints =  NSLayoutConstraint.constraintsWithVisualFormat(stringConstraint, options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views)
        self.view.addConstraints(constraints)
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接