R3ptor R3ptor - 6 months ago 12
Swift Question

update Label with Textfield inside UICollectionViewCell

So I have a CollectionView inside my normal ViewController and if I select a cell and enter something in my textField and press the save Button it should update the nameLabel but I don't know how I can do that. Does anybody have a solution for this?

This is my current code:

private let reuseIdentifier: String = "Item"

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UIGestureRecognizerDelegate, UITextFieldDelegate {

override func viewDidLoad() {
super.viewDidLoad()
ItemCollection.delegate = self
}



func textEnter() {
var text = textField.text

let indexPath = NSIndexPath()
let cell = ItemCollection.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! ItemCell

cell.nameLabel.text = text

}

@IBAction func save(sender: AnyObject, cell: UICollectionViewCell) {
textEnter()
}

@IBOutlet weak var textField: UITextField!
@IBOutlet weak var ItemCollection: UICollectionView!


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}

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

cell.backgroundColor = UIColor(red: 0/256, green: 128/256, blue: 255/256, alpha: 0.66)
cell.nameLabel.text = "Test1"
return cell
}

func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}

}


My Cell:

class ItemCell: UICollectionViewCell {

@IBOutlet weak var nameLbl: UILabel!

}

Answer

There are a couple of things you'll need to do to make this work.

First, you need to preserve context of the clicked cell by storing a "reference" to it. The easiest thing would be to introduce three new variables - section and item. Using these values you'll be able to re-create index path object and reference the cell.

Second, instead of calling dequeueReusableCellWithReuseIdentifier(), you should construct the new Index Path object using the values saved in the previous step and call cellForItemAtIndexPath(_ indexPath: NSIndexPath). This may return a nil if the cell is not in view.

Note: this will set the label only when the user taps Save and the text will most likely be lost if the cell scrolls out of view and then back. In order to preserve this, you should store the entered value in a variable (or refer to the textbox directly) when creating the cell in cellForItemAtIndexPath method.

Modified code example (some of the syntax may be off, I'm doing this from memory):

private let reuseIdentifier: String = "Item"

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UIGestureRecognizerDelegate, UITextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        ItemCollection.delegate = self
    }

    // Store the clicked item location
    private section: Int = 0
    private item: Int = 0

    func textEnter() {
        var text = textField.text

        let indexPath = NSIndexPath(forItem: item inSection:section)
        let cell = ItemCollection.cellForItemAtIndexPath(indexPath) as! ItemCell

        cell.nameLabel.text = text
    }

    @IBAction func save(sender: AnyObject, cell: UICollectionViewCell) {
        textEnter()
    }

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var ItemCollection: UICollectionView!

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 2
    }

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

        cell.backgroundColor = UIColor(red: 0/256, green: 128/256, blue: 255/256, alpha: 0.66)
        cell.nameLabel.text = "Test1"
        return cell
    }

    // Need to capture the tapped cell in here
    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        section = indexPath.section
        item = indexPath.item
    }

    func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }

}