Using xibs/nibs in iOS 7 and Xcode 5
April 9, 2014We recently started a brand new project from scratch and decided to use Xcode’s NIB (abbreviation for NeXT Interface Builder) files to create and layout screens for the application’s user interface. Apple encourages using Storyboards, but we thought nib files would be less hassle with multiple developers and minimize merge conflicts due to version control software (e.g. git.) This debate could be the subject of a whole entire, separate blog post, but that’s for another day. I’ll just highlight some of what we’ve learned using Xcode 5 and nib files (that happen to use the .xib file extension, BTW.)
Create a new project:
So you want to start out your new project, but it seems like every iOS Application template uses Storyboards. Well you’re right, only the simple “Empty Application” does not include a Storyboard.
![XCode Project Template](/uploads/blog/posts/ProjectTemplate.jpg)
But this “Empty Application” is truly empty. There’s not even a view controller to present a view to the user. In fact, if you run the app you’ll likely get a warning: Application should have Root View Controller when ApplicationDidFinishLaunching
.
A common pattern is to create a RootViewController (with no view) to present and switch between other view controllers, in your AppDelegate.m:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // This is code to create a view controller and set window's property UIViewController *rootViewController = [UIViewController new]; self.window.rootViewController = rootVC; // back to boilerplate [self.window makeKeyAndVisible]; return YES;
Manually present a new UIViewController
Easily create a new view controller with a nib file with File -> New -> Cocoa Touch -> Objective-C class and choose subclass of UIViewController and click checkbox “With XIB for user interface.”
![create ViewController with XIB](/uploads/blog/posts/createVCwithXIB.png)
Xcode creates a xib file with the same name as your custom class. Another convenience is that Xcode will automatically load the view and objects contained in the nib when you instantiate the custom class – you can even remove the “Controller” part from end of the filename and the iOS runtime will still find and load the nib.
// in rootVC, create your next view controller and present it MLCustomViewController *nextVC = [MLCustomViewController new]; [self presentViewController:nextVC animated:YES completion:nil];
When you create a view controller this way, you’ll notice that the File’s Owner in the nib is set to a custom ViewController class and an IBOutlet is set from File’s Owner to the View top level object. This is how the iOS run-time can load the nib’s view automatically when the view controller is instantiated.
![Files owner screenshot](/uploads/blog/posts/FilesOwner.png)
Create a ViewController with its view loaded from a custom NIB
When you need to instantiate a view controller with a nib defined in a variable at runtime, use this method:
NSString *aNibName = @"customNibName"; MyViewController* myViewController = [[MyViewController alloc] initWithNibName:aNibName bundle:nil]; [navigationController pushViewController:myViewController];
Load a NIB for a custom UIView subclass
There’s a couple of different ways to load a nib for a UIView (either a subclass or standard UIView.)
UIView *myView = [[[NSBundle mainBundle] loadNibNamed:@"MyViewNib" owner:self options:nil] lastObject]; MyViewClass *customView = [[[UINib nibWithNibName:@"MyCustomView" bundle:nil] instantiateWithOwner:self options:nil] objectAtIndex:0];
Both of these Nib loading methods return an NSArray with its top-level objects. Typically that just means the View (and all of the subviews it contains.) To be extra careful you can use runtime type checking with isKindOfClass:
. If you’ve created a UIView subclass, make sure to set the Custom Class in the Identity Inspector in Interface Builder. The File’s Owner placeholder object can be left blank (at the default, NSObject.) If you get the dreaded class is not key value coding-compliant for the key
Exception, it probably means you have an Outlet in the nib without a corresponding IBOutlet/Action in the class file.
![nib top level object screenshot](/uploads/blog/posts/ViewTopLevelObject.png)
Customize UIView (or subclass) loaded from Nib
It is important to differentiate the object instantiation process when creating objects purely in code or loading them from a nib archive. Methods like initWithFrame:
and initWithStyle
are not called on a UIView subclass when creating it from a nib. Override initWithCoder:
instead.
- (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { // custom initialization here but no IBOutlets, yet } return self; }
One gotcha: IBOutlets are not created until AFTER initWithCoder:
is finished. In order to customize the objects loaded by the Nib, override awakeFromNib
.
- (void)awakeFromNib { self.myButton.layer.borderWidth = 1.0; self.switch.on = YES; }
There is lots more information available from Apple’s Developer website: Resource Management in View Controllers and Resource Programming Guide.
Looking for more like this?
Sign up for our monthly newsletter to receive helpful articles, case studies, and stories from our team.
![Cross tab navigation in Jetpack Compose](https://gratis-creeper.transforms.svdcdn.com/staging/blog/Jetpack-compose-thumbnail.png?w=1080&h=1080&auto=compress%2Cformat&fit=crop&dm=1714051834&s=7ebbaffd42987a5ad4b87e65b2fcefb2)
Cross tab navigation in Jetpack Compose
October 4, 2022Learn how to use Android's Jetpack Compose to navigate from a screen inside of one NavigationBarItem to another.
Read more![Business Model Canvas: Helping business leaders create meaningful digital products](https://gratis-creeper.transforms.svdcdn.com/staging/blog/business-model-canvas-banner.png?w=2134&h=2134&auto=compress%2Cformat&fit=crop&dm=1708017446&s=6819f217da230139bcb0d54fb1fbc189)
Business Model Canvas: Helping business leaders create meaningful digital products
January 17, 2024When it comes to custom software, it’s easy to feel stuck between needing to deliver value quickly, while also ensuring meaningful, long-lasting results. Learn why the Business Model Canvas can help you identify the right digital product for your business needs.
Read more![Between the brackets: MichiganLabs’ approach to software development](https://gratis-creeper.transforms.svdcdn.com/staging/blog/approach-to-software-development-thumbnail_2024-02-15-200634_fdwn.png?w=1200&h=1200&auto=compress%2Cformat&fit=crop&dm=1708027595&s=b1cfebad3bdfb518b25297b50603c688)