Joe
Joe

Reputation: 3961

Passing data between ViewControllers via Collection View cell

I have a rather basic question regarding a UICollectionView, and passing data to multiple view controllers, depending on which cell is pressed.

In ViewController.swift - I have all of the code for displaying the cells within the controller view. As you can see, I have a little print line test that tells me which cell (layout, ultimately) was tapped. This then segue's me to another view controller which is being managed by uniqueViewController.swift.

It is this view controller (uniqueViewController.swift) that I have a label (uniqueLabel), that I would like the text to change depending on which layout was clicked from ViewController. This is the whole passing of data part that has me stumped. Any code snippets and guidance will be appreciated! Thanks.

Screenshot of my main view

ViewController.swift

import UIKit

class CollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate  {


var data = [String]()


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    data = ["Layout one", "Layout two", "Layout three", "Layout four"]


}

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

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

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    var cell = collectionView.dequeueReusableCellWithReuseIdentifier("my cell", forIndexPath: indexPath) as! UICollectionViewCell

    var btnLabel = cell.viewWithTag(1) as! UILabel
    btnLabel.text = data[indexPath.row]

    return cell
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    //println("Cell \(indexPath.row) tapped")
    performSegueWithIdentifier("testSegue", sender: self)

    if((indexPath.row) == 0) {
        println("Layout 1 clicked")

    }
    else if((indexPath.row) == 1) {
        println("Layout 2 clicked")
    }
    else if((indexPath.row) == 2) {
        println("Layout 3 clicked")
    }
    else if((indexPath.row) == 3) {
        println("Layout 4 clicked")
    }

}

}

uniqueViewController.swift

import UIKit

class uniqueViewController: UIViewController {

@IBOutlet weak var uniqueLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    uniqueLabel.text = "I want this labels text unique depending on which cell was tapped from ViewController.swift"

}

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

}

** Updated **

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    //println("Cell \(indexPath.row) tapped")
    performSegueWithIdentifier("testSegue", sender: indexPath.row)

}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let vc = segue.destinationViewController as? uniqueViewController {

        switch(sender as! Int) {
        case 0:
            vc.uniqueLabel.text = "First"
            break
        case 1:
            vc.uniqueLabel.text = "Second"
            break
        case 2:
            vc.uniqueLabel.text = "Third"
            break
        case 3:
            vc.uniqueLabel.text = "Fourth"
            break
        default:
            println("Index out of range.")
        }
    }
}

Upvotes: 1

Views: 4300

Answers (1)

Laffen
Laffen

Reputation: 2771

You should implement prepareForSegue into your CollectionViewController

Example: You have to create a variable in your uniqueViewController to hold the cached string value assigned from the prepareForSegue

class uniqueViewController : UIViewController {
    var clickedCellValue: String!

    override func viewDidLoad(){
       super.viewDidLoad()

       uniqueLabel.text = clickedCellValue
    }
}

In your CollectionViewController, implement the following:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let vc = segue.destinationViewController as? uniqueViewController {

            switch(sender as! Int) {
            case 0:
                vc.clickedCellValue = "First"
                break
            case 1:
                vc.clickedCellValue = "Second"
                break
            case 2:
                vc.clickedCellValue = "Third"
                break
            case 3:
                vc.clickedCellValue = "Fourth"
                break
            default:
                println("Index out of range.")
            }
        }
    }

To be able to retrieve the clicked index, pass the indexPath.row as the sender:

performSegue("testSegue", sender: indexPath.row)

Note: I'm not saying you should do it exactly like this, but this should give you an idea of how you can implement your own solution. You could pass the sender to the uniqueViewController and let the controller convert the index to a string, this depends on how you structure your data sources.

prepareForSegue(_:sender:)

Hope this helps :)

Upvotes: 6

Related Questions