Adding a XIB / NIB file to iOS after the fact - ios

So initially I thought I wasn't going to need XIB files and can generate my view programatically with loadView, therefore, when I modeled out my classes, I decided not to create the XIB file.
Now I changed my mind and decided I DO want a xib file to my already created classes. So I previously had an HomeViewController.m/h files. In XCode, I went File--> New--> User Interface--> View, and created an HomeViewController.xib file.
In my App Delegate, I tried doing this:
HomeViewController *home = [[HomeViewController alloc] init];
self.window.rootViewController = home;
I also tried this:
HomeViewController *home = [[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
self.window.rootViewController = home;
In both cases, I get a SIGABRT error. If I DON'T add the home UIViewController to the rootViewController, I get no error, but obviously nothing on screen.
Thoughts?

Most probably your nib objects refer to other class..
In you xib file..in the identity inspector..make sure every object has the class name of HomeViewController .
Hope it helps.

Try just creating the HomeViewController in the XIB and link it in IB. You can tell it to load the view from another XIB within IB there, and also set the default interface file in your project's properties

Related

Storyboards start game button

I'm looking how to make a start button in storyboards, but it hasnt the initwithnib code to use, like in XLB. I'm using the sprite kit. So far my code is like this.
Viewcontroller.h = mainmenu
#interface ViewController : UIViewController
- (IBAction)PlayBtn:(id)sender;
#end
And in the viewcontroller.m I want to connect it to myScene where the game is. In the myScene.m.
for that I tried using following.
- (IBAction)PlayBtn:(id)sender {
MyScene *game = [[MyScene alloc] initWithNibName:nil bundle:nil];
[self presentViewController:game animated:YES completion:NULL];
}
Although getting error at the initWithNibName doesnt exist. I have only used xlb before but wanted to make a game with sprite-kit.
Here is a screenshot of my storyboard. All graphics are copyrigth protected.
Cheers!
You can mix and match nib files and scenes from storyboards if you like. If you want to do that, create a nibfile (XIB file) and save it to your project. Then use initWithNibName:bundle: as always.
If you haven't created a nib, that won't work.
If you want to load your view controller scene from your storyboard you have a couple of options.
You can set up a segue by control-dragging from your current view controller to another view controller, naming the segue with a unique identifier, and then invoking the segue directly using the view controller method performSegueWithIdentifier:sender:
Another option is to give the scene itself a unique identifier, then instantiate it with instantiateViewControllerWithIdentifier:, and display it using presentViewController:animated:completion: just like you are trying to do now.

My app requires using instantiateViewControllerWithIdentifier - why?

I have added a Storyboard file to an app that initially had none. For some reason, I could not get my custom UIViewController to display correctly until I added this into didFinishLaunchingWithOptions:
ActivityViewController *viewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:#"ActivityViewController"];
Why do I need to force the use of my storyboard like this? The iOS template projects (Single View, Master-Detail etc) doesn't need this.
Checklist:
Xcode Project Summary→Main Storyboard is set correctly to "MainStoryboard".
Interface Builder→Identity Inspector→Class is correctly set to "ActivityViewController".
Interface Builder→Identity Inspector→Storyboard ID is also set to "ActivityViewController", but this is only because it's needed by instantiateViewControllerWithIdentifier.
You do not need to call instantiateViewControllerWithIdentifier if you set Is Initial View Controller on your "ActivetyViewController" in the storyboard. The initial view controller will have an arrow pointing at it.

Contained UIViewControllers - should I use .xib or the storyboard?

I'm making an app that will have a VC doing a similar job as a UITabBarController and I'm using
[self addChildViewController:theViewController];
// [self addSubview ... etc
to put a custom UIViewController's view as a subview of my main (root) VC.
So my question is, which is the correct way to instantiate a VC and not have to build it's UI programatically - from a .xib file, or from a storyboard?
With a xib:
UICustomViewController *controller = [[UICustomViewController alloc] initWithNibName:#"customVC" bundle:nil];
With a storyboard:
UICustomViewController* child = [self.storyboard instantiateViewControllerWithIdentifier:identifier];
I believe .xib files are old stuff and storyboards are the way to go, but I also read this article, which suggests that using a storyboard to do this is a bit hacky. I don't know, any thoughts?
there is nothing any major difference in both way , they are same . but in many other angle storyboard is the straight way, there is nothing any hacky
If you want the child view controller to be present when the app opens, you can do it in a storyboard without any code at all. Add a container view to your root vc, and you will automatically get a view controller embedded in it.

UITableViewController being initialised twice

I was trying to modally present a UINavigationController with a UITableViewController as it's root view but kept crashing the app when pressing the button to present the modal view.
- (IBAction)flipToDefaultsViewController:(id)sender
{
RootTableViewController *controller = [[RootTableViewController alloc] initWithNibName:#"RootTableViewController" bundle:nil];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:controller];
nc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:nc animated:YES];
}
The app crash with the message:
[RootTableViewController numberOfSectionsInTableView:]: message sent to deallocated instance 0x5677b5
When I loaded up Instruments to take a further look it was apparent that two instances of my UITableViewController were created, one with the owner of the UINavigationController and the other by UIKit. The UIKit created instance was the one that was deallocated and causing the crash.
When I changed the initialisation from initWithNibName:bundle: to init the UITableViewController loaded fine (my .xib file was the same name as the class).
My question is why would this happen?
Should you not initialise a UITableViewController this way when adding it to a UINavigationController? I've had a hunt around the documentation with no joy so far.
Using iOS 5 with ARC but target deployment is 4.0.
I haven't worked out why the object was being initialised twice, however I did review the steps that I used to create the .xib file and it looks like there is a problem with copying a view from a Storyboard to Interface Builder. In hindsight this makes sense, but as the view appears to copy without error and everything else seems to look okay it's easily done.
It would appear that similar problems were experienced by others with similar results.
By creating a completely clean subclass of UITableViewController with a nib file (⌘-N) and copying code from the initial class into the new one I'm able to use the initial code above to alloc/init my modal view.
BTW I was mistaken in my opening post about the nib file loading correctly when using init. It wasn't and in fact this behaviour doesn't happen for UITableViewController apparently where as other classes having a class name the same as the .xib file will attempt to load the .xib first.
If this is a button, than you should not initialize anything when the button is pressed. You should initialize beforehand and simply present the modalViewController when the button is pressed.
Is there any reason why the rootViewController and the navigation controller cannot be initialized in the appdelegate didFinishLaunchingWithOptions method?

How can you use a uinavigationcontroller at the root of a xib

My app has two routes to go. Login or using the fun parts of the app. The login uses a navcontroller and the fun parts use a tab bar controller.
I would like to design my nav controller in IB in a xib and the fun parts in a separate xib file with the tab bar controller. Leaving both controllers out of the MainWindow.xib file.
Does anyone know how to do this? I would like to stay away from programmatically setting up those controllers...
The File's Owner is the LoginController a subclass of NSObject. It has 1 outlet to a UINavigationController
Drop the UINavigationController into the nib file.
Connect the navController outlet of the LoginController to the navController you just put in the nib.
Drop in a UIView from the pallet, set it to have a navigation bar at the top.
Connect the VIEW outlet of the "Root View Controller" of the UINavigationController to the view.
In the App Delegate, you now need to load the nib and file's owner but since it is an NSObject it will have to be loaded differently. First you create the file's owner (LoginController). Then, you load the nib with the file's owner. Finally, you set the windows.rootViewController to the LoginController.navController
_loginViewController = [[LoginViewController alloc] init];
[[NSBundle mainBundle] loadNibNamed:#"LoginView" owner:_loginViewController options:nil];
self.window.rootViewController = _loginViewController.navController;
[self.window makeKeyAndVisible];
Technically, the LoginViewController isn't a subclass of UIViewController but it is still the owner of the nib file. So name it however.
You should add the UITabBarController to your main XIB and show the login by creating it in code and presenting it with [self.tabBarController presentModalViewController:myLoginController animated:NO]
You might want to do this because maybe you don't want the user to login every time but save the credentials...
presenting modally also gives you the freedom over modalTransitionStyle when animating back to the tab bar controller.

Resources