0

I have tried to make a UICollectionViewController where I can show a image for each cell. When I want to open this ViewController it shows me an error

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

This is the error/Users/ritscher/Desktop/Bildschirmfoto 2016-03-28 um 13.15.42.png

I have tried a lot to fix it but it allways shows me the same error. I don't know where I have to solve this

6
  • 1
    Put your error in text instead of image is easier for other to help you Commented Mar 28, 2016 at 16:54
  • what return in personService.allPersons().count ? , breakpoint it and check if the data is correct in the array Commented Mar 28, 2016 at 16:55
  • What's is the error in the console log? Commented Mar 28, 2016 at 16:58
  • 1. how can I copy an error? 2. Sorry, I don't get it where I can see what data is in the array. 3. The only error is the one in the picture, in the console log is only a "(lldb)" Commented Mar 28, 2016 at 17:03
  • 1
    This piece of code personService.allPersons()[indexPath.item] is returning nil, so you have to validate before. Commented Mar 28, 2016 at 17:18

2 Answers 2

3

Did you assign the cell identifier ("PersonCollectionCell") to the cell in the xib file or in the storyboard?

I noticed you declared private let reuseIdentifier = "Cell" that you use to register the cell. But you are using a different reuseIdentifier "PersonCollectionCell" when dequeuing the cell.

Also,

I wouldn't recommend using a function personService.allPersons() inside:

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

This method gets called every time a cell will be reuse/dequeued and could bring performance issues in the future. Instead I would save the result inside an array and update it every time something change and can affect what personService.allPersons() returns.

I would declared a lazy variable like this:

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

and in the collectionView datasource methods use allPersons instead of the method itself.

Hope this helps.

Sign up to request clarification or add additional context in comments.

6 Comments

thanks, the first part of your answer helped. It doesn't show an error anymore. But how should I define the number of cells, if I don't use personService.allPersons()? And now it only shows a black screen instead of the CollectionView
When does personService.allPersons() changes the data that returns?
I don't quite get what you mean but the data comes from an other class
Ok, what does that function returns?
It should return all infos of the persons I declared before
|
1

Another problem which is found with your code is in the

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

Here you are trying to register a default UICollectionViewCell and in the cellForItemAtIndexPath you are trying to check for the

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

Here in this code you are checking for your custom cell how this cell become custom cell

if you want to register and create your custom cell your should be like this:

At viewDidLoad()

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

At cellForItemAtIndexPath

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

Default cell
If you want to keep the default cell your code will remain same as it's currently but it will not go inside the condition of custom cell the cell may be show empty if you don't do anything else in the cellforrow


Update Put both of the code in the cellForItemAtIndexPath To change cell background color

cell.contentView.backgroundColor = UIColor.redColor()

As person view is coming nil for now as testing purpose we can add a sample view

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
}

16 Comments

thanks, I have changed that. But it still shows only a black screen without any informations
I'm using a custom cell. where can I see this information when I have set a breakpoint there?
in the left console it shows me persons = 21 values
Ok so are you saying in the allPersons or in the self.personService.allPersons() you got 21 , in the cellForItemAtIndexPath what is the rodelCollectionViewCell.personView?.person some view ? if you can check the value inside it or if you can put the some background color it will be great in narrowing the issue
the personView is nil. How can I change the background? Sorry, for all this basic things
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.