2

I'm using Storyboard and trying to reuse a View for different ViewControllers.

For that, I created a custom .xib (MyCustomView.xib) and class (MyCustomView) as suggested pretty much everywhere.

In my Storyboard I set the custom view to be of type MyCustomView.

In MyCustomView.xib, set First Responder to MyCustomView.

In MyCustomView.m, I added the following method:

-(id)initWithCoder:(NSCoder *)aDecoder{
    if ((self = [super initWithCoder:aDecoder])){
        UIView *myCustomView = [[[NSBundle mainBundle] loadNibNamed:@"MyCustomView" owner:self options:nil] objectAtIndex:0];
        [self addSubview: myCustomView];
    }
    return self;
}

Problem is, [self addSubview: myCustomView] adds a new MyCustomView to existing MyCustomView, so the view is added twice.

How can I get rid of one of the two?

EDIT

My question is not really clear, so I thought some screen caps would help.

Here is my Storyboard with a custom view. Custom class is set to MyCustomView. Storyboard with MyCustomView

(I also added a grey background and a label for testing purpose only)

Now, in MyCustomView.xib, I set File's owner to be of Class MyCustomView: MyCustomView.xib

And add outlets for title Label and imageView: MyCustomView.xib

With the initWithCoder method as written above, this works fine, except when I debug I can see this: MyCustomView.m So self is of course of type MyCustomView, as chosen in the Storyboard, but it contains 2 subviews :

  • First is the test label from my storyboard
  • Second is the view from MyCustomView.xib, itself containing a Label and image view. That's this view I want to get rid of.
Damien
  • 660
  • 6
  • 15
  • The other way to do this, is to do it all in the storyboard -- make your custom view in one controller, and you can copy and paste it into other controllers (delete their default views first, before you paste). – rdelmar Jan 12 '14 at 01:45
  • That may be easier, but each time I modify the view in a controller, have to modify it in each other, that's why I want it in a .xib file. – Damien Jan 12 '14 at 01:50

1 Answers1

0

What is self ?

Here, it is the MyCustomView you just instantiated. So, you're adding a new UIView (not MyCustomView) to your new MyCustomView instance created by the initWithCoder method.

initWithCoder is the method called when loading your storyboard view.

If you want to instantiate a new MyCustomView in your MyCustomViewController you have to call

MyCustomView *newInstance = [[MyCustomView alloc] init];
[self addSubview:newInstance];

Where self is the instance of MyCustomViewController in your storyboard.


EDIT

OK, I understand better your question. If you want to load the MyCustomView nib file, you don't need to create a class for it (except if you have specific variables you want to access in it. Just do what you're doing here, but in the view controller, which will be the self. :)

You might want to have a look at : How to load a UIView using a nib file created with Interface Builder


EDIT 2

Ok, I think I get it :

  • delete the MyCustomView in your Storyboard.
  • create a class MyView or whatever which you attach to the view named "View" in your Storyboard.
  • in the init method of your class you instantiate your MyCustomView nib
  • add the resulting UIView to the views stack like you did it.

self will be MyView (present in the Storyboard), MyCustomView won't appear in the storyboard but created programmatically in the init method of MyView.h

You will have to add constraints programmatically. Here is a post that can be helpful: Adding View Programatically With Auto Layout Gives 'NSGenericException', reason: 'Unable to install constraint on view

Community
  • 1
  • 1
Benoît Lahoz
  • 1,270
  • 1
  • 18
  • 43
  • Yes, I'm sorry, I'm adding a new UIView to MyCustomView. But how to get rid of this particular UIView? Cause in my .xib file, it represents MyCustomView... Thank you – Damien Jan 12 '14 at 01:09
  • Make it simple :-) If you begin a new project in XCode, the default view will be of type UIView in Storyboard. If you want it to be of type MyCustomView, you have only to type it in the right panel (third tab -> custom class). **Don't instantiate a new view in the init of your custom view class**. If you want to instantiate a new view elsewhere, just do like I wrote in this answer. – Benoît Lahoz Jan 12 '14 at 02:44
  • I edited my question with screen caps as I'm afraid it wasn't very clear. I do have specific variables so I need a class for it. Also, I like my approach since I don't have to add any code in my view controllers (it's only handled by the storyboard and my widget view). – Damien Jan 12 '14 at 10:29
  • What are you trying to make actually? Because this code: "UIView *myCustomView = [[[NSBundle mainBundle] loadNibNamed:@"MyCustomView" owner:self options:nil] objectAtIndex:0]; [self addSubview: myCustomView];" does pretty well you are asking him to do - adding new instance of MyCustomView to existing (self) instance of MyCustomView! – m8labs Jan 12 '14 at 10:53
  • Yes, that's why I'm trying to add subviews and constraints of MyCustomView xib to existing (self) instance of MyCustomView, with no success. – Damien Jan 13 '14 at 12:30