Reputation: 2249
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
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