16

I'm trying to create and design a UIView using a storyboard but include it in a UIActionSheet programmatically. This is basically to avoid using CoreGraphics positioning functions with pixels

In old xcode I remember that it was possible to drag a UIView onto the nib without any controllers.

The view obviously has to be connected to the class, so it would have an IBOutlet, but not being added to the self.view

One thing that makes me feel like this should be possible is that if you drag a UIView into the controller black bar in storyboard it pops into place like so:

Snapped in UIView

But its not shown on the screen itself. What is this feature for? Can I somehow open up this view and design it a bit?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Yarek T
  • 9,715
  • 2
  • 28
  • 38

2 Answers2

15

Just create a new .xib file.

  1. Right Click somewhere in the Navigator Area and select 'New File...'.
  2. Select 'User Interface' from the list on the right and Select 'View'.
  3. Click 'Next', 'Next', give your new view a name, and 'Create'.
  4. A new .xib fill will be added to your project.
  5. Double clicking on the new .xib file and it opens in Interface Builder (not Storyboard).
  6. Edit/Design your View to your liking.

Then after you have your new view (.xib) in Interface Builder, it's a simple matter of creating a new subclass of UIView (ex. MyView), switching the class of your new view (.xib) to MyView, creating an instance of MyView in your controller, and adding it as a subview to your other view.


*And to answer your question about that little black bar at the bottom, it's called the 'Dock', and it's just a mini representation of the top-level documents of your scene. The dock is convenient for quickly dragging/dropping icons onto and making connections. See apple's storyboard description here. Ray Wenderlich has an easy to follow tutorial on storyboards here.

eric
  • 4,863
  • 11
  • 41
  • 55
  • The xib view that i've created doesn't honour the bounds that i gave it. It just shows it as filling the entire screen `frame = (0 0; 320 302);`. Do you know if I need to do something special to the xib to set some "fixed" bounds? – Yarek T Jan 03 '13 at 14:21
  • @YarekT Yes, set the 'Size' dropdown to be 'Freeform' under 'Simulated Metrics'. You'll find this under the 4th tab (to the left of the ruler icon) in the inspector pane of the Xcode Utility Area. – eric Jan 03 '13 at 14:35
  • I had that set already. Setting origin didn't change anything ether. The view *is* sized correctly, but its frame and bounds are set to full screen size: http://i.imgur.com/IGQeE.png (The top navbar is *not* part of the xib UIView) – Yarek T Jan 03 '13 at 14:45
  • @YarekT How are you setting your bounds property? – eric Jan 03 '13 at 14:51
  • The bounds on the xib UIView should be set through Storyboard: http://i.imgur.com/oYuo0.png The purple outline are the bounds. Editor > Canvas > Show Bounds Rectangles – Yarek T Jan 03 '13 at 14:58
  • @YarekT I would try setting your bounds for the view programmatically. As in : myview.bounds = CGRectMake(...) – eric Jan 03 '13 at 15:08
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22129/discussion-between-yarek-t-and-eric) – Yarek T Jan 03 '13 at 15:13
9

You cannot have a UIView outside of a UIViewController on a storyboard. I'm guessing it's because the storyboard would have no idea how to identify or instantiate with the current API. It is something I've had a use for myself. The solution is just use a XIB for the one UIView and load it up programmatically (just like used to do). I've found using a storyboard for most items and couple XIBs for re-usable views across multiple view controllers do work nicely together.

Here is some code I use to load a XIB as part of a custom object with the object gets initialized.

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        [[[NSBundle mainBundle] loadNibNamed:@"BannerView" owner:self options:nil] objectAtIndex:0];
        [self addSubview:self.view];
        self.frame = self.view.frame;
    }
    return self;
}

As for dragging views down into the black bar on the storyboards. Those views are still part of the UIViewController, but they aren't a `subview' of the top level view. I think the document outline shows the hierarchy nicely.

The following view has 2.1.1 View, 2.1.2 View, etc outside of my main view hierarchy because they aren't subviews of my main view. The result is, they won't be displayed by default. I do have IBOutlets setup and I conditionally add/remove them from my main view hierarchy using the standard addSubview: and removeFromSuperview.

IB Document Outline example

DBD
  • 23,075
  • 12
  • 60
  • 84
  • So would it be possible to create a fully designed subview, with buttons, labels and whatnot, and then drag it to the bar and make it a top level view, to be switched programatically? EDIT: The answer seems to be no, Table view controller doesn't like not having a `UITableView` =/ I think storyboard UI still needs a bit of work – Yarek T Jan 03 '13 at 13:51
  • I have not tried that, but it would probably cause issues in the more complicated view controllers. I tend to use it for overlays which are normally not visible to the user. It removes the clutter of hidden objects from my storyboard and probably speeds up the view (insignificantly) by keeping them off them main view unless needed. – DBD Jan 03 '13 at 14:01
  • @Eric Because Storyboard doesn't let you create a UIView without a UIViewController. I figured if it let me drag the view into the dock and not a subview then I can connect it to UIActionSheet programatically. As you rightly pointed out the solution is to create a separate xib with just the view – Yarek T Jan 03 '13 at 14:16