How to Convert a Nib-Based Project to a Storyboard-Based

How to convert a NIB-based project to a Storyboard-based?

There is not a 1-click way to do this. According to "Sams Teach Yourself Core Data for Mac and iOS in 24 Hours" by Jesse Feiler, storyboards are different enough in their developer interfaces that it makes sense not to convert existing nib but to use them for new projects. One of the larger differences the way view transitions are handled. However, I did take the plunge and feel it was worth it because I was still near the beginning of a larger project. Doing so will entail a manual process. Apple Converting to Storyboards Release Notes addresses how to add storyboard to the project. This will get you a storyboard but your existing xibs will not be imported into the storyboard. I didn't do this. I started with a fresh project and copied over the custom view controller classes I wanted to re-use (.h and .m). Then I proceeded to build my storyboard and cut and pasted from the old projects xib files using interface builder when it made sense. It really doesn't take that long. After you assign your custom view controllers to the control your views in storyboard you will want to take out the IBActions out of your code that select view transitions and replace them with storyboard segues. The segues are added in storyboard and you have the option of adding a prepareForSegue method in your view controller. The optional prepareForSegue method is used finishing up anything in the source view controller and setting up the destination view controller before the transition.

How to convert a NIB-based project to a Storyboard-based?

There is not a 1-click way to do this. According to "Sams Teach Yourself Core Data for Mac and iOS in 24 Hours" by Jesse Feiler, storyboards are different enough in their developer interfaces that it makes sense not to convert existing nib but to use them for new projects. One of the larger differences the way view transitions are handled. However, I did take the plunge and feel it was worth it because I was still near the beginning of a larger project. Doing so will entail a manual process. Apple Converting to Storyboards Release Notes addresses how to add storyboard to the project. This will get you a storyboard but your existing xibs will not be imported into the storyboard. I didn't do this. I started with a fresh project and copied over the custom view controller classes I wanted to re-use (.h and .m). Then I proceeded to build my storyboard and cut and pasted from the old projects xib files using interface builder when it made sense. It really doesn't take that long. After you assign your custom view controllers to the control your views in storyboard you will want to take out the IBActions out of your code that select view transitions and replace them with storyboard segues. The segues are added in storyboard and you have the option of adding a prepareForSegue method in your view controller. The optional prepareForSegue method is used finishing up anything in the source view controller and setting up the destination view controller before the transition.

How to convert xib to storyboard?

I think "no" is the short answer. I raised a Radar with Apple last year but they've not done anything yet!

You can sometimes open the XIB and copy and paste the controls into your Storyboard, but the formatting is sometimes wrong and you still have to adjust the outlets and actions manually.

There is no reason why you can't use both Storyboards and XIBs in a single project; maybe that's the best approach in the short term.

Equivalent Storyboard function for Nib

This is pretty easy to do. Just make an NSViewController subclass (or an NSWindowController subclass if you want it to control a whole window) for each of the two views. For each view, override -init and have it call super's implementation of -initWithNibName:bundle: with the name of the view's nib file:

@implementation MyViewController

- (instancetype)init {
self = [super initWithNibName:@"MyViewController" bundle:nil];

if (self == nil) {
return nil;
}

return self;
}

Note that if you can require a sufficiently recent version of macOS (I think it's 10.11 and higher off the top of my head, but it's possible that I could be off by a version or so), you don't even have to do this much, because NSViewController will automatically look for a nib file with the same name as the class.

Anyway, now you should be able to instantiate a MyViewController and insert its view into your view hierarchy, and manipulate it the same way you'd manipulate any other view:

MyViewController *vc = [MyViewController new];

[someSuperview addSubview:vc.view];

If you want to do windows instead, you can make an NSWindowController subclass instead of NSViewController. NSWindowController is slightly more annoying to use, since its initializers that take nib names are all convenience initializers, whereas the designated initializer just takes an NSWindow. So if you're using, say, Swift, you can't do it the way I did it above with NSViewController. Objective-C, of course, generally lets you do whatever you want, so you actually can get away with just calling super's -initWithWindowNibName:owner:, and I won't tell anyone, wink wink, nudge nudge. However, to be stylistically correct, you probably should just call -initWithWindow: passing nil, and then override windowNibName and owner:

@implementation MyWindowController

- (instancetype)init {
self = [super initWithWindow:nil];

if (self == nil) {
return nil;
}

return self;
}

- (NSNibName)windowNibName {
return @"MyWindowController";
}

- (id)owner {
return self;
}

This should get you a window controller that you can just initialize with +new (or +alloc and -init if you prefer), then call its -window property and manipulate the window as normal.

Extracting nibs/xibs from storyboards (iOS)

I found that the simplest method was to copy and paste the items out of the storyboard, one view at a time, and recreate the view controllers for each one.

However, for anybody who does this, note that you have to make a xib for MainWindow in addition to all of your other XIBs, and hook it up accordingly, including setting up the window and app delegate. Storyboards handle all of this for you, so when you try to avoid them, you have a lot of manual setting up that creating non-storyboard projects from the get-go handles for you. Don't do what I did, and try to make your root controller your main view controller, because it will go nuts saying things about how UIApplication isn't key-value compliant for individual properties of your XIB.

Load view from an external xib file in storyboard

My full example is here, but I will provide a summary below.

Layout

Add a .swift and .xib file each with the same name to your project. The .xib file contains your custom view layout (using auto layout constraints preferably).

Make the swift file the xib file's owner.

Sample Image
Code

Add the following code to the .swift file and hook up the outlets and actions from the .xib file.

import UIKit
class ResuableCustomView: UIView {

let nibName = "ReusableCustomView"
var contentView: UIView?

@IBOutlet weak var label: UILabel!
@IBAction func buttonTap(_ sender: UIButton) {
label.text = "Hi"
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)

guard let view = loadViewFromNib() else { return }
view.frame = self.bounds
self.addSubview(view)
contentView = view
}

func loadViewFromNib() -> UIView? {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: nibName, bundle: bundle)
return nib.instantiate(withOwner: self, options: nil).first as? UIView
}
}

Use it

Use your custom view anywhere in your storyboard. Just add a UIView and set the class name to your custom class name.

Sample Image



Related Topics



Leave a reply



Submit