RPTokenControl icon indicating copy to clipboard operation
RPTokenControl copied to clipboard

RPTokenControl is not always initialised correctly

Open crispinb opened this issue 11 years ago • 6 comments

If RPTokenControl is created in IB by editing the Custom Class field in an NSView subclass that isn't substituted with an NSCustomView, it won't get initialised properly. In this kind of case, -initWithCoder: is called instead of -initWithFrame:, but initWithCoder isn't implemented.

This can happen, for example, by following these steps:

  • drag an NSScrollView object onto an IB NSView canvas
  • expand the Scroll View document outline (results in Bordered Scroll View -> Clip View -> View)
  • edit the Custom Class field of the above leaf view to be RPTokenControl

This ends up looking exactly like the setup of the RPTokenControl demo app, but the latter somehow ends up with an NSCustomControl in the IB file, whereas the above steps don't. There's no visual indicator of this difference in IB, but it's clear from the source XML. I'm not sure how to account for the difference -- my tests are on Xcode 5.1, using the 10.9 SDK.

The solution is presumably to use a common initialise routine to be called from both initWithCoder: and initWithFrame:

I haven't supplied a patch as, being to date primarily an iOS developer, this is slightly unfamiliar territory, and I may have got the wrong end of the stick somewhere (iOS doesn't have the NSCustomView, and all IB objects are initialised with initWithCoder:).

crispinb avatar Dec 09 '13 00:12 crispinb

Hello, crispinb. Welcome to Mac development. You are basically correct. RPTokenControl inherits from NSControl, which conforms to NSCoding, RPTokenControl should override the coding methods to initialize itself and, ugh, encode/decode its instance variables. I'll fix it.

jerrykrinock avatar Dec 09 '13 02:12 jerrykrinock

Thanks for the welcome!

My assumption was that you would only need to call on super's implementation and then set the defaults currently in initWithFrame:, as the primary use is decoding from a Nib, which is really only going to be providing the skeleton NSControl implementation (ie. without any RPTokenControl-specific variables). I can see you'd need a full implementation if you were writing an IBPlugin, but otherwise?

And I also assumed that no encodeWithEncoder implementation would be needed for typical use-cases.

I'd be interested to know why in your view the instance vars needed en/decoding. In any case thanks for giving it your attention.

crispinb avatar Dec 09 '13 06:12 crispinb

Oops - I see you've already done the fix, and put enough explanation in the comments. Thanks again.

crispinb avatar Dec 09 '13 07:12 crispinb

Oh, I forgot to reply to the issue. Commits are so easy nowadays :)) Anyhow, yes I think I've fixed it, but because my applications don't use the encoding/decoding methods, they are completely untested. Let me know if you have any trouble.

jerrykrinock avatar Dec 09 '13 12:12 jerrykrinock

There is one further problem. If an RPTokenControl is initted via initWithCoder:, target and action are always nil. I gather (and again I stress my relative ignorance of AppKit here) that this is because there's no associated NSCell. It look to me like NSView's implementation of initWithFrame: creates a cell of the class specified in the cellClass class method, but initWithCoder doesn't.

The naive approach is presumably to allocate and init an action cell manually in RPTokenControl's overridden initWithCoder, but perhaps there's a more standard idiom for approaching this.

crispinb avatar Dec 17 '13 03:12 crispinb

This will require some more thought, which I have not had time for lately. If you've had any more ideas since Dec 16, crisping, please share them.

jerrykrinock avatar Dec 26 '13 07:12 jerrykrinock