3

I made a UICollectionView in my app but I can't figure out how to display different data for each cell I'm stuck with the same image I set it to in storyboard

the searching I've done has not resulted in any tutorials but I know that I customize my data in the UICollectionViewCell custom class

class CollectionViewCell: UICollectionViewCell {
    //drawing a blank here...
}

if you could help me out I just want to put a button, two images and a couple labels (2-3) for each cell (there will be about 12 cells and I need them to have different data for each because i am trying to make a character selection screen)

with my current setup

class CharacterViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

var array = [UIImage(named: "ideal image"),UIImage(named: "ideal image"),UIImage(named: "ideal image")]

override func viewDidLoad() {
    super.viewDidLoad()


    // Do any additional setup after loading the view.
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return array.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FirstCollectionViewCell", for: indexPath) as! FirstCollectionViewCell

    return cell
}

}

i am able to display three of the exact same image but i need the cells to have separate customizable data i know all about .xib files and cocoa touch classes i use em all the time

one site i saw suggested using .xib files for each cell which i dont mind setting up but i need to know how to register the .xib files to be displayed as a cell if you know how could you help me out?

here is my cell

image for cell

you guys are a huge help i think i know how to do it

  1. make cells with custom .xib files
  2. register .xib cells to array
  3. load array of cells into collectionView
  4. enjoy custom collectionView
E. Huckabee
  • 1,598
  • 8
  • 26
  • Maybe, you should try the following link: https://stackoverflow.com/questions/37315466/how-to-load-custom-cell-xib-in-uicollectionview-cell-using-swift – Piyush Verma Sep 06 '17 at 09:24
  • its working now just one issue its saying " Ambiguous reference to member 'collectionView(_:numberOfItemsInSection:)'" anybody know how to fix? – E. Huckabee Sep 06 '17 at 10:00

3 Answers3

2

In your controller you have to set this:

    Class yourController : UIViewController,UICollectionViewDelegate, UICollectionViewDataSource{...
 //at some point 
yourCollectionView.delegate = self
yourCollectionView.dataSource = self

and then you include this method and you'll be able to load the data you want in each cell:

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell: yourCell = collection.dequeueReusableCell(withReuseIdentifier: nameCelda, for: indexPath) as! yourCell
//dataArrayOrWhatever -> An array of data for each row
        let dataForCelll =  dataArrayOrWhatever[indexPath.row]
//functions defined on your yourCell.Swift
        cell.setImage(imageName: someMethodWithDataForImage(data: dataForCell))
        cell.setTitle(title: someMethodWithDataForTitle(data: dataForCell))

Hope it helps you ;)

  • could you please be more specific with your let dataforcell = dataArrayOrWhatever[indexPath.row] i dont understand – E. Huckabee Sep 06 '17 at 09:13
  • @E.Huckabee this answer should help your question. If you only want show different data on each cell you only need a `Dictionary` from indexPath.row . `I just want to put a button, two images and a couple labels (2-3) for each cell (there will be about 12 cells and I need them to have different data for each) ` or you asking about the custom cell. Not clear to me – MrX Sep 06 '17 at 09:31
  • i am making a character selection screen – E. Huckabee Sep 06 '17 at 09:36
  • in my question i said 12 but that will change when i update with more characters to play please check my edited answer for some new info – E. Huckabee Sep 06 '17 at 09:45
  • You only have one array right, then have you try this answer? . You need get a Dictionary of `indexPath.row` from your array then show it based their index. – MrX Sep 06 '17 at 09:55
  • So, first of all you need to think about the differences between characters views. Are all the views the same but only change the name, some stats, an image? If they are very similar you can use the same custom cell, and you only have to pass different data to each view. If the cell will change drastically you should declare diferent custom cells, but it isnt as efficient due to iOS won't be able to reuse the cells. About "dataArrayOrWhatever" it is an object with the data of all characters in order to be able to fetch data programmatically with an didentifier, in this case the row ;) – Jaime Sendra Domenech Sep 07 '17 at 10:12
2

There are more than 1 way to achieve it. Bu your code it seems customcell is used The code for it

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CollectionViewCell

      cell.backgroundColor = UIColor.white

         if indexPath.section == 0 {

      cell.imageView.image = image
                }
         if indexPath.section == 1 {

      cell.imageView.image = image
                }
      return cell
 }

override func numberOfSections(in collectionView: UICollectionView) -> Int {
              return 2 // whatever you want
}

         //2
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

         return searches[section].searchResults.count // if each section have same cell

         if section == 0 {
                return 2
            } else if section == 1 {
                return 3
         }
}

Link to customcell for collectionview

Jamil Hasnine Tamim
  • 3,459
  • 20
  • 39
cole
  • 2,452
  • 2
  • 11
  • 25
0

Here's an example you can follow :

class CollectionViewCell: UICollectionViewCell {

let myButton : UIButton = {
    let btn = UIButton(type: .system)
    btn.translatesAutoresizingMaskIntoConstraints = false
    btn.setTitle("My button", for: .normal)
    return btn
}()

override init(frame: CGRect){
    super.init(frame: frame)
    setupViews()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func setupViews(){
    // Add subViews to your custom cell
    addSubview(myButton)
    myButton.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
    myButton.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    myButton.widthAnchor.constraint(equalToConstant: 200).isActive = true
    myButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
}

}

Next step, you have to register cell class like this in viewDidLoad:

collectionView.register(CollectionViewCell.self, forCellReuseIdentifier: "customCell")

Last step, in cellForItemAt function you define :

let cell = collectionView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomViewCell
        return cell
Tung Vu Duc
  • 1,204
  • 1
  • 11
  • 20
  • tried this its giving me an error " Ambiguous reference to member 'collectionView(_:numberOfItemsInSection:)'" – E. Huckabee Sep 06 '17 at 09:16
  • I think you should read more documents about collectionView (https://stackoverflow.com/questions/17856055/creating-a-uicollectionview-programmatically) – Tung Vu Duc Sep 06 '17 at 09:19
  • what im trying to do is make a character selection screen and each cell displays the character portrait and stats, price, etc. and when you tap on the character you want it pushes to a different view controller (i know its possible because angry birds the app has it in its level select menu) is this possible with collection views or should i use something else – E. Huckabee Sep 06 '17 at 09:25