1

I have a UIView subclassed on a custom collectionView cell. It displays fine but in the "didSelect" delegate method in my ViewController I set a property for the UIView which refreshes with a setNeedsDisplay and drawRect isn't being fired. Does it have anything to do with the dequeueReusableCell? How would that be coded? This is in swift 1.2 not obj-c.

class setSelection: UIView {

    private var _checked: Bool = false

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

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setNeedsDisplay()
    }

    override func drawRect(rect: CGRect) {
        super.drawRect(rect)
     . . . code . . .   
    }

    var checked: Bool {
        get {
            return _checked
        }
        set {
            _checked = newValue
            self.setNeedsDisplay()
            println(_checked)
        }
    }

This is the UIView class. the checked property is being set in the collectionView didSelectCell. The setNeedsDisplay in the property doesn't fail but drawRect will never be called again.

** UPDATE ** The init functions are not required and should be removed.

cheborneck
  • 61
  • 5
  • In the viewController I set a property in the UIView class which executes the setNeedsDisplay. The drawRect isn't executed. – cheborneck Aug 29 '15 at 03:05
  • The setNeedsDisplay is executed but the drawRect is only triggered when the class is initialized – cheborneck Aug 29 '15 at 03:51
  • I tried to post a code snippet but couldn't get it formatted. – cheborneck Aug 29 '15 at 03:52
  • Yeah it says put four spaces in front of a line. Code and pre didn't work. – cheborneck Aug 29 '15 at 03:57
  • Have a look here http://stackoverflow.com/questions/27678582/swift-uiview-drawrect-how-to-get-drawrect-to-update-when-required – brandonscript Aug 29 '15 at 04:10
  • My guess is that it's not firing because you're calling `setNeedsDisplay()` inside of the `_checked` setter? You also probably can't call it inside of `init` since the view doesn't exist then. Try doing it in `viewDidLoad()` just to see if it'll work? – brandonscript Aug 29 '15 at 04:19
  • I can't test right now but the code came from an obj-c example. I of course modified the setter slightly but the init is the same. I'll be able to look at it in a couple hours. Thanks. Tom – cheborneck Aug 29 '15 at 04:21
  • When you can, put a breakpoint in the init and step through each line to see whether `setNeedsDisplay()` is even called. – brandonscript Aug 29 '15 at 04:23
  • setNeedsDisplay() is being called but the view is only updated when the cell is initialized and scrolled out and back into view. Just to add, The collectionView is using a custom collectionViewCell which has an IBOutlet to the UIView which has the problem. I see lots of people online having this problem and no real solid solutions. Especially not in Swift. – cheborneck Aug 29 '15 at 14:05
  • In the code above you can take out the init because they aren't a factor and aren't being used. The instantiation happens when the cell is created by the outlet (when the cell comes into view HINT). – cheborneck Aug 29 '15 at 14:08
  • one more bit of peculiar behavior (to me) is setting the UIView contentMode to other than redraw makes no difference. I was under the assumption anything with a custom drawRect had to be set to redraw – cheborneck Aug 29 '15 at 14:36
  • the layering of the collectionViewCel is the custom redrawn UIView sits on top of an image which sites on top of the cell object. Another HINT maybe. – cheborneck Aug 29 '15 at 14:39
  • Any chance you can try with Swift 2.0? I could very well be a legit bug. – brandonscript Aug 29 '15 at 16:20
  • I only have a production machine – cheborneck Aug 29 '15 at 20:45

1 Answers1

0

SOLVED!! I knew it had something to do with cell reference. In researching the problem i realized that in collectionView didSelectItemAtIndexPath and didDeselectItemAtIndexPath I was referencing the reusable cell which is only valid for cells in view and are only updated in cellForItemAtIndexPath:

let selectedCell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) as! ImageDataCell

which would select the appropriate cell but do nothing with it. Instead I needed to reference the actual cell:

let selectedCell = collectionView.cellForItemAtIndexPath(indexPath) as! ImageDataCell

now the view is refreshed while displayed when this method is executed. You still need to set the cell in cellForItemAtIndexPath because that refreshes cells that move back into frame but doesn't refresh a cell being selected or deselected.

cheborneck
  • 61
  • 5