Background color on NSView?


Gary L. Wade
 

No, I'm not talking about subclassing NSView. I'm talking about writing two category methods in Objective-C, setBackgroundColor: and backgroundColor. In Swift, you'd call a category an extension. With the setter and getter, you don't need your pBackgroundColor object; just use the backgroundColor property on the layer. You might try an Internet search on NSView backgroundColor category if you're not familiar yet with the concept.
--
Gary L. Wade
http://www.garywade.com/

On Aug 29, 2017, at 9:22 AM, Dave <dave@...> wrote:

Hi,

I’m not worried about having it initialised in initWithCode, as I it up there explicitly from other data anyway (I’ve added this to a subclass of NSView because all my Basic Custom View classes inherit from this class). Is this basically what you meant? LTWNativeColorClass is either NSView or UIView, but in this case it will always be NSView.

#if TARGET_OS_OSX

-(void) setBackgroundColor:(LTWNativeColorClass*) theBackgroundColor
{
if (self.pBackgroundColor == theBackgroundColor)
return;

self.pBackgroundColor = theBackgroundColor;
if (theBackgroundColor == nil)
return;

[self setWantsLayer:YES];
[self.layer setBackgroundColor:[theBackgroundColor CGColor]];
}
#endif



On 29 Aug 2017, at 17:06, Gary L. Wade <garywade@...> wrote:

What I do is write an extension on NSView with a setter and getter for backgroundColor that calls through to the view's layer property's backgroundColor, calling wantsLayer before doing so in the setter. Note that the layer won't be instantiated during an initWithCoder call prior to 10.13; you'll need to redo this in 10.12 and earlier. I find most cases I can get around this with a dispatch async to re-call the setter if I have a nil layer after setting wantsLayer to true; eventually it sticks, and I haven't seen too many significant issues, but you need to be sure that works for you. Apple fixed this initWithCoder/wantsLayer bug in 10.13, at least it's still fixed for now. I do this for all the good stuff, cornerRadius, borderColor, borderWidth, etc., just like in iOS on UIView.
--
Gary L. Wade
http://www.garywade.com/

On Aug 29, 2017, at 7:51 AM, Dave <dave@...> wrote:

Hi All,

I’ve just realised that NSView don’t have a background colour. I remember hitting this a long while ago and got around it by using a layer and adding a “setBackgroundColor” method to my Class.

Does anyone know how to do this? I can’t find the code or a reference to it now.

All the Best
Dave

PS

As you may have gathered I’m porting code between iOS and Mac and Vice Versa, if anyone else is doing this kind of thing, I’ve found the following Macro’s VERY handy:


#if TARGET_OS_IPHONE

#define LTWPlatformKitHeaderFile <UIKit/UIKit.h>

#define LTWNativeViewControllerClass UIViewController
#define LTWNativeViewClass UIView
#define LTWNativeImageClass UIImage
#define LTWNativeImageViewClass UIImageView
#define LTWNativeColorClass UIColor
#define LTWNativeBezierClass UIBezierPath

#define LTWNativeViewIdentifierMethod accessibilityIdentifier

#define LTWNativePointType CGPoint
#define LTWNativeSizeType CGSize
#define LTWNativeRectType CGRect

#elif TARGET_OS_OSX

#define LTWPlatformKitHeaderFile <AppKit/AppKit.h>

#define LTWNativeViewControllerClass NSViewController
#define LTWNativeViewClass NSView
#define LTWNativeImageClass NSImage
#define LTWNativeImageViewClass NSImageView
#define LTWNativeColorClass NSColor
#define LTWNativeBezierClass NSBezierPath

#define LTWNativeViewIdentifierMethod identifier

#define LTWNativePointType NSPoint
#define LTWNativeSizeType NSSize
#define LTWNativeRectType NSRect


#else

#error !!!!!NO PLATFORM SPECIFIED!!!!

#endif





Dave
 

Hi,

I’m not worried about having it initialised in initWithCode, as I it up there explicitly from other data anyway (I’ve added this to a subclass of NSView because all my Basic Custom View classes inherit from this class). Is this basically what you meant? LTWNativeColorClass is either NSView or UIView, but in this case it will always be NSView.

#if TARGET_OS_OSX

-(void) setBackgroundColor:(LTWNativeColorClass*) theBackgroundColor
{
if (self.pBackgroundColor == theBackgroundColor)
return;

self.pBackgroundColor = theBackgroundColor;
if (theBackgroundColor == nil)
return;

[self setWantsLayer:YES];
[self.layer setBackgroundColor:[theBackgroundColor CGColor]];
}
#endif

On 29 Aug 2017, at 17:06, Gary L. Wade <garywade@...> wrote:

What I do is write an extension on NSView with a setter and getter for backgroundColor that calls through to the view's layer property's backgroundColor, calling wantsLayer before doing so in the setter. Note that the layer won't be instantiated during an initWithCoder call prior to 10.13; you'll need to redo this in 10.12 and earlier. I find most cases I can get around this with a dispatch async to re-call the setter if I have a nil layer after setting wantsLayer to true; eventually it sticks, and I haven't seen too many significant issues, but you need to be sure that works for you. Apple fixed this initWithCoder/wantsLayer bug in 10.13, at least it's still fixed for now. I do this for all the good stuff, cornerRadius, borderColor, borderWidth, etc., just like in iOS on UIView.
--
Gary L. Wade
http://www.garywade.com/

On Aug 29, 2017, at 7:51 AM, Dave <dave@...> wrote:

Hi All,

I’ve just realised that NSView don’t have a background colour. I remember hitting this a long while ago and got around it by using a layer and adding a “setBackgroundColor” method to my Class.

Does anyone know how to do this? I can’t find the code or a reference to it now.

All the Best
Dave

PS

As you may have gathered I’m porting code between iOS and Mac and Vice Versa, if anyone else is doing this kind of thing, I’ve found the following Macro’s VERY handy:


#if TARGET_OS_IPHONE

#define LTWPlatformKitHeaderFile <UIKit/UIKit.h>

#define LTWNativeViewControllerClass UIViewController
#define LTWNativeViewClass UIView
#define LTWNativeImageClass UIImage
#define LTWNativeImageViewClass UIImageView
#define LTWNativeColorClass UIColor
#define LTWNativeBezierClass UIBezierPath

#define LTWNativeViewIdentifierMethod accessibilityIdentifier

#define LTWNativePointType CGPoint
#define LTWNativeSizeType CGSize
#define LTWNativeRectType CGRect

#elif TARGET_OS_OSX

#define LTWPlatformKitHeaderFile <AppKit/AppKit.h>

#define LTWNativeViewControllerClass NSViewController
#define LTWNativeViewClass NSView
#define LTWNativeImageClass NSImage
#define LTWNativeImageViewClass NSImageView
#define LTWNativeColorClass NSColor
#define LTWNativeBezierClass NSBezierPath

#define LTWNativeViewIdentifierMethod identifier

#define LTWNativePointType NSPoint
#define LTWNativeSizeType NSSize
#define LTWNativeRectType NSRect


#else

#error !!!!!NO PLATFORM SPECIFIED!!!!

#endif



Gary L. Wade
 

What I do is write an extension on NSView with a setter and getter for backgroundColor that calls through to the view's layer property's backgroundColor, calling wantsLayer before doing so in the setter. Note that the layer won't be instantiated during an initWithCoder call prior to 10.13; you'll need to redo this in 10.12 and earlier. I find most cases I can get around this with a dispatch async to re-call the setter if I have a nil layer after setting wantsLayer to true; eventually it sticks, and I haven't seen too many significant issues, but you need to be sure that works for you. Apple fixed this initWithCoder/wantsLayer bug in 10.13, at least it's still fixed for now. I do this for all the good stuff, cornerRadius, borderColor, borderWidth, etc., just like in iOS on UIView.
--
Gary L. Wade
http://www.garywade.com/

On Aug 29, 2017, at 7:51 AM, Dave <dave@...> wrote:

Hi All,

I’ve just realised that NSView don’t have a background colour. I remember hitting this a long while ago and got around it by using a layer and adding a “setBackgroundColor” method to my Class.

Does anyone know how to do this? I can’t find the code or a reference to it now.

All the Best
Dave

PS

As you may have gathered I’m porting code between iOS and Mac and Vice Versa, if anyone else is doing this kind of thing, I’ve found the following Macro’s VERY handy:


#if TARGET_OS_IPHONE

#define LTWPlatformKitHeaderFile <UIKit/UIKit.h>

#define LTWNativeViewControllerClass UIViewController
#define LTWNativeViewClass UIView
#define LTWNativeImageClass UIImage
#define LTWNativeImageViewClass UIImageView
#define LTWNativeColorClass UIColor
#define LTWNativeBezierClass UIBezierPath

#define LTWNativeViewIdentifierMethod accessibilityIdentifier

#define LTWNativePointType CGPoint
#define LTWNativeSizeType CGSize
#define LTWNativeRectType CGRect

#elif TARGET_OS_OSX

#define LTWPlatformKitHeaderFile <AppKit/AppKit.h>

#define LTWNativeViewControllerClass NSViewController
#define LTWNativeViewClass NSView
#define LTWNativeImageClass NSImage
#define LTWNativeImageViewClass NSImageView
#define LTWNativeColorClass NSColor
#define LTWNativeBezierClass NSBezierPath

#define LTWNativeViewIdentifierMethod identifier

#define LTWNativePointType NSPoint
#define LTWNativeSizeType NSSize
#define LTWNativeRectType NSRect


#else

#error !!!!!NO PLATFORM SPECIFIED!!!!

#endif


Dave
 

Hi All,

I’ve just realised that NSView don’t have a background colour. I remember hitting this a long while ago and got around it by using a layer and adding a “setBackgroundColor” method to my Class.

Does anyone know how to do this? I can’t find the code or a reference to it now.

All the Best
Dave

PS

As you may have gathered I’m porting code between iOS and Mac and Vice Versa, if anyone else is doing this kind of thing, I’ve found the following Macro’s VERY handy:


#if TARGET_OS_IPHONE

#define LTWPlatformKitHeaderFile <UIKit/UIKit.h>

#define LTWNativeViewControllerClass UIViewController
#define LTWNativeViewClass UIView
#define LTWNativeImageClass UIImage
#define LTWNativeImageViewClass UIImageView
#define LTWNativeColorClass UIColor
#define LTWNativeBezierClass UIBezierPath

#define LTWNativeViewIdentifierMethod accessibilityIdentifier

#define LTWNativePointType CGPoint
#define LTWNativeSizeType CGSize
#define LTWNativeRectType CGRect

#elif TARGET_OS_OSX

#define LTWPlatformKitHeaderFile <AppKit/AppKit.h>

#define LTWNativeViewControllerClass NSViewController
#define LTWNativeViewClass NSView
#define LTWNativeImageClass NSImage
#define LTWNativeImageViewClass NSImageView
#define LTWNativeColorClass NSColor
#define LTWNativeBezierClass NSBezierPath

#define LTWNativeViewIdentifierMethod identifier

#define LTWNativePointType NSPoint
#define LTWNativeSizeType NSSize
#define LTWNativeRectType NSRect


#else

#error !!!!!NO PLATFORM SPECIFIED!!!!

#endif