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.
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.
Related Topics
Uicollectionview Decoration View
Uiviewcontentmodescaleaspectfill Not Clipping
Launch Image Not Showing Up in iOS Application (Using Images.Xcassets)
Autolayout: Add Constraint to Superview and Not Top Layout Guide
First App Update, User Data Lost (Was Stored in Documents Directory)
Xcode 4/iOS - Send an Email Using Smtp from Inside My App
When to Use Takeunretainedvalue() or Takeretainedvalue() to Retrieve Unmanaged Objects in Swift
Waiting for Multiple Asynchronous Download Tasks
How to Prompt the User to Turn on Location Services After User Has Denied Their Use
iOS - Parse Issues in Nsobjcruntime, Nszone, and Nsobject
How to Get an Iphone's Device Name
Mkmapview Mkpointannotation Tap Event
Restore Already Bought In-App-Purchases on Iphone
Add Lefthand Margin to Uitextfield
How to Download a File and Save It to the Documents Directory with Afnetworking
Custom Uitableviewcell Programmatically Using Swift
Screenshot Showing Up Blank - Swift
How to Use Keychain for Saving Password Like Generickeychain Sample Code