ios - 使用 AutoLayout 以编程方式创建 UICollectionView

标签 ios swift autolayout uicollectionview

我正在尝试使用 AutoLayout 以编程方式创建 UICollectionView,但我遇到了一些问题。

第一次测试:

在我的第一次尝试中,我创建了一个 UICollectionView 作为 Lazy var 并将其添加到 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)
}

这个方法让我犯了这个错误:

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

第二个测试:

所以我不得不使用 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...

}

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

所以我决定摆脱 autoLayout,看看它的工作方式。

第三个测试:

 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 与 AutoLayout 一起使用?

解决方案

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

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

最佳答案

过了一会儿,我发现我的问题出在约束上。然后我想出了这个解决方案:

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

关于ios - 使用 AutoLayout 以编程方式创建 UICollectionView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33770558/

相关文章:

ios - MPMediaQuery 从 persistentID 返回轨道而不是播放列表

ios - 体系结构的重复符号 [arm7、arm64]

java - 在 iOS (Swift) 上进行 RSA 签名并在 Java 中进行验证

arrays - 在 Swift 2.2 中附加数组时使用 'subscript' 不明确

macos - Mac OS X 自动布局 - 展开以填充 super View

ios - 另一个 uiscrollview 自动布局问题

ios - youtube-ios-player-helper 无法在 Youtube 应用中打开视频

由于 cordova-plugin-geolocation,iOS PhoneGap 应用被应用商店拒绝

swift - 暂停和恢复 SKScene

ios - 以编程方式且没有尺寸类别的不同设备方向的各种自动布局约束?