20

I'm new to iOS and Xcode. I can't figure out how to design a separated view and make it be added into the main UIViewController using storyboard.

I did different approaches..

  1. Just grab an UI object from right-bottom corner window in the xcode, and then put it onto any space area of storyboard. But I can't drop the UI object like the way with xib.
  2. Add a new UIViewController. Add a view into the UIViewController. In the main ViewController.m, I get the new UIViewController instance in the viewDidLoad, and then [self.view addSubview:newUIViewController.view]. But I can't see the added view.
  3. I created a new xib file. And add a view into it. I also try to get the instance in the main ViewController. And addSubview with the xib's view. But it also failed.

Is there a correct way or any working solution to do so?

Ravi Gautam
  • 960
  • 2
  • 9
  • 20
shiami
  • 7,174
  • 16
  • 53
  • 68
  • possible duplicate of [How do I create a custom iOS view class and instantiate multiple copies of it (in IB)?](http://stackoverflow.com/questions/9251202/how-do-i-create-a-custom-ios-view-class-and-instantiate-multiple-copies-of-it-i) – Max MacLeod Apr 18 '13 at 15:57

2 Answers2

36

I figured out a way to do it. Described as following:

  1. Create a .xib file. For example: MyView.xib
  2. Create a objective-c class. For example: MyViewClass.h and MyViewClass.m
  3. Set the .xib File's Owner to the class.
  4. Add a UIView element on the storyboard and set the custom class to the objective-c class name (MyViewClass).
  5. The key-point is to override the initWithCoder method in the object-c class.

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

The idea is the custom class is loaded by the storyboard and initWithCode will be called. The index 0 is the root view in the .xib interface builder.

It's kind of tricky but it works.

Pranav Jaiswal
  • 3,752
  • 3
  • 32
  • 50
shiami
  • 7,174
  • 16
  • 53
  • 68
  • 1
    I do something very similar, but I don't do `owner:self` because I don't want all the outlets/action/code for my XIB embedded in my view controller (and normally I want to re-use in many places). I create a subclass of a `UIView` then `alloc` and `init` that subclass and set that to be the owner. – DBD Oct 15 '12 at 16:32
  • 2
    Your code sample is actually instantiating two copies of your view, one by the storyboard when it calls `initWithCoder:` and your call through to super, and another when you call `loadNibNamed:` to load the view from the nib. What you _actually_ want to be doing, which is even more hacky, is `self = [[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil][0]` in your initWithCoder method, and _not_ call through to `[super initWithCoder:]` – Alex Pretzlav Feb 27 '13 at 19:49
  • 2
    @AlexPretzlav : it seems like when you want to return a different self, a "NSGenericExpection : this coder requires that replaced objects be returned from initwithcoder" is raised. So you really have to add it as a subview. – Ben G Feb 28 '13 at 13:52
  • 3
    doesn't this create 2 views? one in the storyboard and one on code? Becuase one its created in the Storyboard and one its created at the initcode. According to what I have tested, it seems two are created. – S.H. Nov 12 '13 at 02:51
  • 1
    You saved my day and my yesterday :D – Lolloz89 Jun 25 '14 at 10:30
0

In storyboard, drag and drop a view controller. The view controller come with a main view. Select that main view by clicking outside of the added view controller and then clicking in the center of it. Now, just drag a uiview or whatever into that main view just like you did with IB.

T.J.
  • 3,942
  • 2
  • 32
  • 40