1

This is my first try with IB_DESIGNABLE on Xcode.

I have this class to add color to a NSView.

header

#import <Cocoa/Cocoa.h>


IB_DESIGNABLE @interface NSViewComCor : NSView

@property (nonatomic, weak) IBInspectable NSColor *backgroundColor;

@end

implementation

#import "NSViewComCor.h"

@implementation NSViewComCor

@synthesize backgroundColor = _backgroundColor;

- (void)awakeFromNib {

  [super awakeFromNib];

  [self setWantsLayer:YES];
  self.backgroundColor = [NSColor whiteColor];  //default color
}

- (NSColor *) backgroundColor
{
  CGColorRef colorRef = self.layer.backgroundColor;
  return [NSColor colorWithCGColor:colorRef];
}

- (void) setBackgroundColor:(NSColor *)backgroundColor
{ // color should change when changed on interface builder inspectable color box
  self.layer.backgroundColor = backgroundColor.CGColor;
  _backgroundColor = backgroundColor;
}

even with IB_DESIGNABLE, this class does not render with the correct color on interface builder... why?

Duck
  • 34,902
  • 47
  • 248
  • 470
  • "does not render with the correct color" That's meaningless. What color _does_ it show? – matt Jan 16 '15 at 01:46
  • "color should change when changed on interface builder inspectable color box". No, that is not how Inspectable works. – matt Jan 16 '15 at 01:47
  • white. Not meaningless: I adjust the color on interface builder, it continues white on interface builder and it continues white when I run the app. – Duck Jan 16 '15 at 01:49

1 Answers1

4

As the point out in WWDC 2014 "What's New in Interface Builder" video, you have to:

  1. Create framework.

  2. Create class.

  3. Mark view as designable (and properties as inspectable).

  4. Go back to the main project and specify the base class in Interface Builder.

For example, I added a new "framework" target to the project, and added the following NSView subclass source to that framework:

IB_DESIGNABLE @interface CustomView : NSView

@property (nonatomic, strong) IBInspectable NSColor *backgroundColor;

@end

and

@implementation CustomView

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    [self.backgroundColor setFill];
    NSRectFill(dirtyRect);
}

@end

Then, when I went back to my main project and tried adding this CustomView as a subview on my storyboard, the "background color" was IB "inspectable" and I could see the changes in the color immediately rendered in IB.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Ok, works like a framework but will it only work if it is a framework? That's awful. – Duck Jan 16 '15 at 04:26
  • I hate that only working if it is a framework. Frameworks are awful to mantain. Thanks anyway for your amazing help. – Duck Jan 16 '15 at 04:30
  • When the framework is a dependent target within the project, it's really not that bad. But I hear you. But given that IB is actually running your code, it's not a crazy requirement that it be an isolated, self-standing bit of code. Also, it's worth noting that while the WWDC video was quite specific that framework is required, I notice that it appears to work in iOS targets without framework. I'm not sure I'd want to rely upon that, but it might be an indication that some flexibility may be contemplated in the future. – Rob Jan 16 '15 at 04:46
  • Right, I was going to ask about that. I'm iOS only these days and we no longer have the framework requirement. – matt Jan 16 '15 at 04:49
  • 1
    Xcode has to be able to build the target that includes the `IB_DESIGNABLE` code. So if you put it in your main target, if you're working on issues that prevent its successful compilation, the view may not always be dynamically previewable in IB. If you put it in a separate framework target, it's easier to ensure that (a) it compiles quickly; (b) it won't have to recompile as frequently; and (c) won't be adversely affect by work-in-progress in the main target. So I don't know if there are additional reasons why Apple instructed us to use framework, but there are compelling pragmatic reasons. – Rob Jan 18 '15 at 17:07
  • Where in the video is this framework mentioned? Would be much easier if this information is available in the post. – zic10 Mar 17 '16 at 15:22
  • 1
    @zic10 - I'd really suggest watching the whole video if you haven't seen it. But, in answer to your question, the first half of the video is predominantly about live views. They demonstrate the creation of the separate framework roughly 7:45 into the video. They articulate the rationale for this separate framework roughly 27:48 into the video. – Rob Mar 17 '16 at 16:01
  • BTW, if working with `NSView`, I've noticed it doesn't render designables for the top-level view. See http://stackoverflow.com/questions/38906727/ibdesignable-view-not-rendering. – Rob Dec 22 '16 at 16:34