iOS开发: UICollectionView的使用(swift版,解决cell不显示)

UICollectionView类似于Android里的GridView,九宫格效果。使用起来也不算复杂,跟TableView差不多,之所以写篇博文,是因为地学习过程中遇到了一个大坑,希望对其他新人有所帮助。 环境:Xcode 6.1.1 Swift语言 新建SingleView Application,删除默认的ViewController类,清空Main.storyboard。 往Main.storyboard拖进一个Collection View Controller,默认会有一个Collection View,往Collection View里拖进一个Collection View Cell,这个Cell就相当于是一个Item,接下来往Cell里随便拖个label,button之类的控件,用于测试。 选中cell,切换到Attributes inspector,将Identifier设为”cell”,无引号,字符串。这个id是用于复用item View的,跟Android的Adapter的复用机制一样。 选中Collection View Controller,切到Attributes inspector,将View Controller下的Is Initial View Controller勾选,这一步是声明这个View Controller是第一个ViewController,打开应用时展示这个。 新建Cocoa Touch Class,继承UICollectionViewController,名为CollectionViewController,打开会发现自动生成了一堆代码,很多已经注释掉,我们暂时先不管他们。 注意几个方法:

override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    //#warning Incomplete method implementation -- Return the number of sections
    return 1
}

这个是Section数量,所谓Section就是分组。这里返回1,只有一组。

override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //#warning Incomplete method implementation -- Return the number of items in the section
    return 50
}

这个是对应分组的item数量,因为没有分组,不需要判断section,直接返回50

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as UICollectionViewCell

    return cell
}

这个是最重要的方法,相当于Android的getView,返回一个item的View,reuseIdentifier就是我们之前在Main.storyboard给Cell定义的id,这里需要把reuseIdentifier常量改为”cell”,与前面定义相同。 运行… 发现问题了没?什么都没有显示…并没有展示我们之前往cell里拖的控件。坑就在这,根据Apple的文档,不能直接给UICollectionViewCell添加subView,而是要添加到UICollectionViewCell的contentView里,我们添加UICollectionViewCell时,并没有自动添加一个contentView,就相当于直接加到了UICollectionViewCell里。但是拖进UITableViewCell是有一个contentView的。这应该是xCode的一个bug吧,解决方法,只有用代码写cell的布局了.

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as UICollectionViewCell
    //如果是复用的Cell,viewWithTag就不会返回nil
    var label:UILabel? = cell.contentView.viewWithTag(TAG\_CELL\_LABEL) as? UILabel
    if label == nil {
        //非复用,创建并添加到contentView里
        println("label == nil\\(indexPath.item)")
        label = UILabel(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        label!.tag = TAG\_CELL\_LABEL
        cell.contentView.addSubview(label!)
    }
    label!.text = "\\(indexPath.item)"
    return cell
}