在 UICollectionViewController 中显示单元格

Showing Cells in UICollectionViewController

我尝试制作一个 UICollectionViewController,我可以在其中显示每个单元格的图像。当我想打开这个 ViewController 它显示错误

import UIKit

private let reuseIdentifier = "Cell"

class RodelCollectionViewController: UICollectionViewController {

var personService: PersonService!

override func viewDidLoad() {
    super.viewDidLoad()
    assert(personService != nil, "Person Service has to be set, otherwise this class can't do anything useful.")
    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Register cell classes
    self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1
}

override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return personService.allPersons().count
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("PersonCollectionCell", forIndexPath: indexPath)

    if let rodelCollectionViewCell = cell as? RodelCollectionViewCell {
        rodelCollectionViewCell.personView?.person = personService.allPersons()[indexPath.item]
    }

    return cell
}

// MARK: - Navigation

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if let PersonDetailViewController = segue.destinationViewController as? PersonDetailViewController,
        let person = (sender as? RodelCollectionViewCell)?.personView?.person {
        PersonDetailViewController.person = person
    }
}

这是错误

我已经尝试了很多方法来修复它,但它总是向我显示相同的错误。我不知道我必须在哪里解决这个问题

您是否将单元格标识符 ("PersonCollectionCell") 分配给 xib 文件或故事板中的单元格?

我注意到您声明了 private let reuseIdentifier = "Cell" 用于注册单元格。但是您在使单元格出列时使用了不同的 reuseIdentifier "PersonCollectionCell"

此外,

我不建议在里面使用函数 personService.allPersons():

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell

每次单元格 reuse/dequeued 时都会调用此方法,并且将来可能会带来性能问题。相反,我会将结果保存在一个数组中,并在每次发生变化并影响 personService.allPersons() returns.

时更新它

我会像这样声明一个惰性变量:

private lazy var allPersons: [WhateverTheTypeIs] = {
    let allPersons = self.personService.allPersons()
    return allPersons
}

并且在 collectionView 数据源方法中使用 allPersons 而不是方法本身。

希望对您有所帮助。

在您的代码中发现的另一个问题

 self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

此处您尝试注册默认的 UICollectionViewCell,而在 cellForItemAtIndexPath 中您尝试检查

if let rodelCollectionViewCell = cell as? RodelCollectionViewCell {
    rodelCollectionViewCell.personView?.person = personService.allPersons()[indexPath.item]
}

在此代码中,您正在检查自定义单元格,该单元格如何成为自定义单元格

如果你想注册并创建你的自定义单元你应该是这样的:

viewDidLoad()

self.collectionView!.registerClass(RodelCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

cellForItemAtIndexPath

let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! RodelCollectionViewCell

默认单元格
如果您想保留默认单元格,您的代码将保持与当前相同,但它不会进入自定义单元格的条件 单元格可能显示为空 如果您在 cellforrow

中不做任何其他事情

更新 将两个代码都放在 cellForItemAtIndexPath 更改单元格背景颜色

cell.contentView.backgroundColor = UIColor.redColor()

作为测试目的,人物视图暂时变为零,我们可以添加示例视图

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("PersonCollectionCell", forIndexPath: indexPath)

    if let rodelCollectionViewCell = cell as? RodelCollectionViewCell {
        rodelCollectionViewCell.personView?.person = personService.allPersons()[indexPath.row]
    }
   cell.contentView.backgroundColor = UIColor.redColor()
   let lbl = UILabel(frame:CGRectMake(0,0,100,21))
   lbl.text = "\(indexPath.row)" //replace this value with your original value if it displays for the first time
   cell.contentView.addSubview(lbl)

    return cell
}