Cristian Pena
Cristian Pena

Reputation: 2249

IBDesignable not working in Objective-C

I have many reusable views designed with nibs, all of them subclasses of a class NibView

class NibView: UIView {

var view: UIView!

func setupNib(nibName:String) {
    view = loadViewFromNib(nibName)
    view.frame = bounds
    view.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
    addSubview(view)
}

func loadViewFromNib(nibName:String) -> UIView {
    let bundle = NSBundle(forClass: self.dynamicType)
    let nib = UINib(nibName: nibName, bundle: bundle)
    let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
    return view
}

}

Which I subclass like this

@IBDesignable class ExampleView: NibView {

@IBOutlet weak var label: UILabel!

private var _property:Int = 0
@IBInspectable var property:Int {
    set {
        _property = newValue
        label.text = "\(newValue)"
    } get {
        return _property
    }
}

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

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

func setup() {
    setupNib("ExampleView")
}

override func layoutSubviews() {
    super.layoutSubviews()
    // custom init

}
}

In the NIB file, I set the File's owner as ExampleView. Everything works perfectly and both storyboards and xibs render everything live.

Now, doing the same thing in Objective-C, doesn't work

IB_DESIGNABLE

@interface ExampleView : NibView

@property (nonatomic) IBInspectable NSUInteger count;

@end


@implementation NibView

- (void)setupNib:(NSString *)nibName {
    self.view = [self loadViewFromNib:nibName];
    self.view.frame = self.bounds;
    self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self addSubview:self.view];
}

- (UIView *)loadViewFromNib:(NSString *)nibName {
    UIView *view = [[[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil] objectAtIndex:0];
    return view;
}

@end

And

@implementation ExampleView

- (id)init {
     self = [super init];
     if(self) {
        [self setup];
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame {
     self = [super initWithFrame:frame];
     if(self) {
        [self setup];
    }
     return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
     self = [super initWithCoder:aDecoder];
     if(self) {
        [self setup];
    }
     return self;

}

- (void)setup {
    [self setupNib:@"ExampleView"];
     // Custom init
}

Any idea?

Upvotes: 4

Views: 1128

Answers (1)

dpalmetz
dpalmetz

Reputation: 31

I know the question is old, but I had a similar problem, and as there are not many examples on this for Objective C, I would like to share my solution.

You are not using the same code in Objective C as in SWIFT. In Objective C you are trying to access the main bundle, but when trying to load the view in the IB, there is no main bundle. This piece of code works for me:

NSBundle *bundle = [NSBundle bundleForClass:self.classForCoder];
self.view = [[bundle loadNibNamed:@"HighscoreLabelView" owner:self options:nil] objectAtIndex:0];

Upvotes: 3

Related Questions