i'm developing an app for the iPhone, and i'm having a bit of trouble with switching views and xibs and storyboards etc. I have gotten everything to work as in switching the views, but when i change to my game view from my main menu, it seems that instead of entirely switching views, it just appends all the objects i added programmatically etc to the same storyboard for some reason, i can see the previous page in the background while the game completely loads and works. The buttons from the previous views also seems to still still work, but are just "ghost buttons" as in i can click them through the new view.
It's almost as if the old view never unloads but just stays there in the background, while the new view gets added on top of the old view. I'm using Xcode Version 5.0.1 (5A2053) and developing for iOS 7. the methods i use for switching views are:
From Storyboard to Xib:
[self presentViewController: [iphoneGame alloc] animated: NO completion:nil];
From Xib to Storyboard:
ViewController *viewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewController"];
[viewController setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:viewController animated:NO completion:nil];
Your code to load a VC from an XIB is wrong. You don't create a view controller with alloc/init. You need to use initWithNibName:bundle:. If you pass in nil for both, the system should use the nib name that's the same as the class name.
Why are you trying to mix and match VCs from XIBs and storyboards? That's fairly unusual. Most people either use one or the other, and if you're going to do it, the burden is on you to get everything set up correctly.
In my view controller if I navigate through the Root view controller it works okay through this code,
[self.navigationController popToRootViewControllerAnimated:YES];
But when i try to custom navigation to viewcontroller through below code,
ViewController2 *vc = [[[ViewController2 alloc] init]];
[self.navigationController popToViewController:vc animated:YES];
by this my application is crashed and show me the Below error:
terminate called throwing an exception.
Help me to shortout it.
uinavigation just like a box , you can push anyVC in this box , but when you want to out ,you just popToRootVC .. you can't push VC that it outside in this box .
You can only use that method to pop to a vc already in the array of view controllers.
EDIT: as developer new to iOS, you need to spend the time to read (and re-read) the UINavigation Controller class description, and the two or three Apple Guides on using UIViewController and the catalog of various view controller. Yes, its a lot of stuff to read and comprehend - but then, all of us doing iOS work now have done it too. There is no magic way to get your app to work. Your use of popToViewController demonstrates to the community that you have not done the above, as you would not have posted the question if you'd read the documents.
People who try to help others here on SO are much more likely to do so if it appears you have made an honest effort to get something to work, but are stymied in some way where an experienced person can provide insight.
I'm developing my first iPhone app. I'm still not very good at Xcode and my question is pretty simple. I'm using Xcode 5 and I'm using storyboards in my project.
Well, I have some images in a View Controller. I'd just like that if I tap one of those images I switch to another View Controller, nothing else. How do I exactly do that?
I looked for a solution online and I found out on YouTube that I have just to Control-Click my image and connect it to another view using a modal connection, without any code. However I tried in the simulator and it doesn't work. Also, most of tutorials online are outdated and they explain how to do it on Xcode 4.2 and without using storyboards.
Can you help me please? Thank you.
Try this:
HomeViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"Home"];
[self presentViewController:vc animated:YES completion:nil];
with Home is Storyboard ID of Home Screen
You can't just use a UIImage. You need to use a UIButton and then under the properties set the button to custom and set background image to the image you want. Then you can click and drag from the button to the new view and choose modal.
I'm having you choose modal because from what I can gather, you aren't using a navigation controller. Therefore you'd modally want to present the view controller.
I am trying to add a navigation controller inside a tab bar controller in a brand new non-storyboard (plain old nib) style.
I found this demo which assumes that XCode has a new project template called "Tab Bar Application". It doesn't. Now XCode 4.6 has "New Tabbed Application". Of course, Apple in their great wisdom has decided that I should not have a main window nib (.xib) and should have the tab bar controller and its pages coded for me in the app delegate instead of in a new-user-friendly NIB instantiated tab controller. I guess that's because it's more flexible that way, and you can write code to decide what tabs the user sees and what tabs they don't see. If I turn on Storyboards, then I guess I can do everything visually still.
I am deeply confused by the long and tortured history of XCode version differences, which affect the validity of existing questions on stackoverflow and demos elsewhere on the web, that reference different iOS versions, and different XCode versions, and make assumptions specific to versions of XCode and iOS that now appear to have changed, and which each rely on different choices with respect to the contents of your Main Nib File Base Name being set or not set.
I also find that it seems that pre-storyboard-Nibs and the complexities of combining various UIKit widgets and controllers has been a primary motivation behind the creation of storyboards.
I am working in a real non-storyboard nib-based application that appears to have been created before this change of heart at apple, and I can see that at startup a lot of unecessary views are created automatically by nib-instantiation and then deleted, in order to dynamically hide and show tabs on the tab bar controller. This appears to have been thought about a great deal at Apple, and they've changed the recommended practices implicitly by changing the way new applications are generated in XCode. I'm not questioning their wisdom, in fact I appreciate the change, but it's left me lost and confused.
Anyways, I'm just trying to put a navigation controller inside a tab in the main tab bar, and I already have an application that must have been started back when XCode used to generate a main window and generate a "Tab Bar Application" with a top level view that is a tabbed view, and the tab bar controller is nib instantiated. The demo above assumes as much.
Apple apparently famously never has provided a demo of this obvious combination of tab bar plus navigation controller. Or so I'm told. And the Apple Human Interface Guidelines apparently state (or used to state?) that it's better to put a navigation controller inside a tab bar than vice versa, and my question should be understood as wishing to comply with the HIG however possible, so I believe I'm asking about the recommended combination, not the discouraged combination.
Here's what I've tried so far:
Tried to follow this blog post, from circa 2009, which assumes things true about older versions of XCode that are no longer true.
Starting with a new tabbed application which XCode generated for me, with storyboards turned OFF, I have a root app delegate .m file that it generated for me that apparently creates at app-startup time, a Tab Bar Controller object completely in code, and which has no Main Window nib. The following code is entirely written by Apple, and I am wondering where (as a relatively new Cocoa developer) I'm supposed to break into this and place my new stuff, if I wanted to change one of the tabs to hav a nav bar and its associated UINavigationViewController:
-- This marker helps stackoverflow's busted markdown system not be confused --
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1, *viewController2;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController1 = [[RPDAFirstViewController alloc] initWithNibName:#"RPDAFirstViewController_iPhone" bundle:nil];
viewController2 = [[RPDASecondViewController alloc] initWithNibName:#"RPDASecondViewController_iPhone" bundle:nil];
} else {
viewController1 = [[RPDAFirstViewController alloc] initWithNibName:#"RPDAFirstViewController_iPad" bundle:nil];
viewController2 = [[RPDASecondViewController alloc] initWithNibName:#"RPDASecondViewController_iPad" bundle:nil];
}
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
It now appears that what used to be possible without writing code (according to that 2009 example on the blog I linked to) is now done purely in code. I have read about 500 pages of "Programming iOS 5", worked for a few hundred hours on my first app, and tried a lot of demo applications but I'm still a relatively unseasoned Cocoa/iOS developer, and I believe part of my confusion over all this is the "controller and view" pattern, and its rules for combining them, both in code, and in nibs, are not entirely clear to me.
--
Update: You can has teh codez! In the interest of helping out future XCode-cocoa-iOS noobs like me, I have made a complete demo app and posted it on github here.
Screenshot:
I was as confused as you were when I did the same thing, but once you understand the structure you will find out that it is quite simple.
Basically, You want to create a UINavigationController with the RootViewController you want to display first:
[UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:theViewControllerYouWantToDisplayFirst];
Then just add this controller to the array for your tab buttons.
NSArray *tabs = [[NSArray alloc]
initWithObjects: navController, otherTab, etc];
Then, set your tabs using such array.
UITabBarController *rootController = [[UITabBarController alloc] init];
[rootController setViewControllers:tabs];
and add it to your tab controller to your window:
[self.window setRootViewController:rootController];
And that is it. I took me some time to realize the way things are structured. The Tab View controller just holds a bunch of ViewControllers, you just need to make one of those view controllers your NavigationController.
If you don't mind starting a new app to get the basics going, try this:
Create a Tabbed Application (or whatever it's called nowadays):
Then select the view you want to have embedded in a NavigationController.
Then go to Editor -> Embed -> in NavigationController like shown below:
Your result will look like this:
Cheers!
As explained in the first two answers (both correct), I add another method to come back to the original "Tabbed Application" template (maybe version 3 of XCode? I don't remember).
In this template you'll have a main xib file with, inside, your TabBarController.
You must start from the Empty Application template, then go through this steps:
Add a new file, User Interface, Application Xib. In this tutorial I'll assume you will name it "Application.xib"
Go to your AppDelegate.h file and change this line:
#property (strong, nonatomic) UIWindow *window;
adding IBOutlet:
#property (strong, nonatomic) IBOutlet UIWindow *window;
Go inside AppDelegate.m and change your applicationDidFinishLaunching method with this
:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// delete all and leave only the return
return YES;
}
Go inside Application.xib, select "App Delegate" from the Objects Menu, and then in the identity inspector change the Class --> write AppDelegate (or your AppDelegate.h class name)
Always in Application.xib, right click again on App Delegate Object, you will see a "window" Outlet --> link it to the Window object in the Object inspector on the left
Now, come back to the project, go in supporting files, main.m and change the return line like this:
:
return UIApplicationMain(argc, argv, nil, nil);
then, go inside the main .plist file and add a key: right click, add, key, "Main Nib File Base Name", Type String, Value "Application" (without quotes, without .xib extension)
Ok, now you have an empty "old style" nib application. Now you can go again inside Application.xib, drag your TabBar and link it as the Window "root view controller" (right click on the Window, link the root view controller property).
Then, inside the tab bar, you can drag ViewControllers, Navigation controllers, ecc...
If you need other details or images write me
EDIT:
I uploaded a sample project if you want to look: http://www.lombax.it/documents/ManualTab.zip
Screenshot:
I had a working application that I wanted to place under one "leg" of a tabbed application. I wanted to develop other portions of the "bigger app" under the other tabs. I didn't want to use storyboards. That removed a good deal of the solutions I found. Most of the remaining solutions were developed using older versions of Xcode and they simply wouldn't work with the version of Xcode I downloaded in Feb of 2013.
I tried creating my own tabbed application - (starting with an "Empty Application") as some of the developers on this thread had used. I felt like I was getting close, but I simply couldn't get it to work.
There is an excellent tutorial on using a "Tabbed Application with a Navigation Controller" by Vishal Kurup.
With a minor modification (listed below) by following the video I was able to slip my existing application under the default "Tabbed Application" created by Xcode.
Create a TabBar Controller with a Navigation Controller + Detail View in Xcode 4.3
can be found at
http://www.youtube.com/watch?v=UMpNbCs4mr4
the only real change I had to make from the default "Tabbed Application" was in the AppDelegate.m:
the following code supplied by the selecting "Tabbed Application" wouldn't serve my purpose
self.tabBarController.viewControllers = #[viewController1, viewController2];
this did
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navigation ,
viewController1 ,viewController2, viewController3, viewController4, nil];
A big thank you goes out to Mr Vishal Kurup.
He has made a number of quality videos on iOS development.
I am developing an application that loads a web page (using UIWebView) using Storyboard (I do know nothing about previous xib neither). I have already created a view controller for that UIWebView and everything works fine. The thing is: since previous versions of iOS don't allow to upload files, I need to make a new view (scene I thought it is called) that allows the user to pick and post a picture. I am able to develop both views separately and they work as expected but now I need to connect them based on event triggered when user wants to post a picture to the server. Using shouldStartLoadWithRequest I can catch that action, then I need to redirect to new view (which contains image picker and a button in order to upload the selected image) if iOS version is below 6.0 but I am really lost when it comes to load the new controller to show that view. Using buttons it is trivial but I don't know how to called inside the code. So far, I have a view controller linked to that scene and I have tried these ways:
WritePostViewController *postViewController = [[WritePostViewController alloc] init];
[self.navigationController pushViewController:postViewController animated:YES];
And even calling the storybard:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
[sb instantiateInitialViewController];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"WritePostView"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
The first approach does nothing and second one shows this error log:
* WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: Storyboard () doesn't contain a view controller with identifier 'WritePostView'*
I have been browsing and reading a lot but nothing solves my problem. For sure this a problem with my not-so-large knowledge about iOS but I am really stuck. I will thank any help.
By the way, I need to come back after posting the file but I could imagine it is the same way opposite direction, right?
If your code is inside a view controller (which it seems to be), you can get the current storyboard with self.storyboard. You also don't need instantiateInitialViewController because, if all your UI is coming from the same storyboard, it has already gone through the loading of the initial controller.
As for the actual error, it's complaining that #"WritePostView" isn't a recognized name for any view controller in the storyboard. Note that what it looks for here is not the class name for the controller but the Storyboard ID for the controller. (Which makes sense since you could have different "scenes" with the same type of controllers.)
Ok, it seems is solved. I just have added a segue between scenes
and then I just need to add this one:
[self performSegueWithIdentifier:#"writePostViewSegue" sender:self];
and it works!. Anyway, I am not sure if it is the way to do it, so if someone knows better, please let me know.
Cheers