Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restore bindings in UICollectionViewCell after it is decoded

I have a subclass of UICollectionViewCell. The cell is visually designed in the storyboard with lots of components and these components are bound to the variables in Swift subclass using the storyboard.

The Swift class just provides logic for populating the components from dat retrieved from the data-source.

For example:

class InfoCollectionViewCell : UICollectionViewCell {

    @IBOutlet weak var mainPanel : UIView!
    @IBOutlet weak var panel1 : UIView!

    @IBOutlet weak var firstName : UILabel!
    @IBOutlet weak var lastName : UILabel!
    @IBOutlet weak var address : UILabel!
    etc ...

    func setVariousProperties(etc) {
        firstName.text = ... etc

The data-source does the usual thing:

let cell = collectionView.dequeueReusableCellWithReuseIdentifier("InfoCell", forIndexPath:indexPath)
if let c : InfoCollectionViewCell = cell as? InfoCollectionViewCell {
    c.setVariousProperties(...)
}

I originally only implemented decode/encode methods containing a "not implemented" assertion, but it became apparent that occasionally the framework was encoding and decoding the class. I implemented dummy encode/decode methods without saving the components resulted in predictable problems with nil values when the components were accessed.

So it appears that I am required either to implement encoding and decoding of all the controls in the UICollectionViewCell subclass one-by-one, or I have to find a better way.

It seems a waste of time as I don't actually need (I don't think) to save the contents of the components since they are just going to be for re-use anyway by the subclass: I will overwrite the component contents will values from the datasource.

Obviously, all of the controls are defined in the storyboard. I could manually fetch them by name from the storyboard in the init method, but that seems equally tedious and makes the graphical linking of the controls and variables redundant.

Is there a better way?

Can I just say "restore connections" or something like that?

EDIT:

Somewhere between posting the question and adding the bounty, the problem stopped happening. I now notice that the encode method of my components is not getting called. So for some reason, the framework was deciding to serialise my objects and deserialise them, but now it isn't. Hence the problem is not occurring and I am not able to supply a stack-trace.

It is conceivable that some update to XCode has fixed this issue, or it could be something else.

I am obviously still concerned there is some bug lurking there somewhere.

like image 739
rghome Avatar asked Jan 12 '16 22:01

rghome


1 Answers

You shouldn't need to implement encoding/decoding for any of the controls that have been laid out and connected in the Storyboard. This will be taken care of at runtime and you will get a cell back after the collectionView.dequeueReusableCellWithReuseIdentifier as long as everything else has been connected correctly with the UI components ready to use. The things to check are:

  1. The subclass is specified in the storyboard custom class section
  2. The reuseIdentifier is defined to match the string you expect
  3. All the IBOutlets are connected and should also show the connections in the code next the IBOutlet var lines.

Once you have ensured these are right try printing out the components to check if they are still nil and placing some simple text in there to eliminate any dataSource problems:

  func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("InfoCell", forIndexPath:indexPath)
    if let c = cell as? InfoCollectionViewCell{
      print(c.address)
      print(c.firstName)
      print(c.lastName)

      c.firstName.text = "firstName Test"
      c.lastName.text = "lastName Test"
      c.address.text = "address Test"
    }
    return cell
  }
}
like image 197
Dallas Johnson Avatar answered Oct 19 '22 12:10

Dallas Johnson