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.
Related
I am developing an application with iOS 9 based SDK , this is my first time I am working with Storyboards , I have 20 view controllers, each scene has Next / Previous buttons to go back and forward . I have a huge problem with going forward !. If I move from scene 1 to for example to scene 15 I received memory warning and then application crashes . I have searched and it seems there is method called unwind segue but it seems this is for going back ! it's something like dissMiss method .
I connect each scene with line in Interface Builder :
Here is segue's setting :
I would be grateful if you help me out .
EDITED :
I tried to present a view controller programmatically but result was the same ! .
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
WhatIsDino *vc = (WhatIsDino*)[mainStoryboard instantiateViewControllerWithIdentifier:#"WID"];
[self presentViewController:vc animated:YES completion:nil];
Seems like it's a problem of wrong approach, and not the storyboard.
Let me guess, since before storyboard you used to change your app's rootViewController to the next/previous screen once you tap on the arrow button. So previous screen are released and deallocated from memory once you set a new rootViewController.
And now you're presenting every next view controller modally, which involved creating new UIWindow and loads all the hierarchy of you screen and keeps previous underneath the new one so it holds the memory and you're getting out of memory crash.
Well, you can do rootViewController approach with a storyboard too since it's just another way to manage your screens while development. Storyboard offers additional features like segues, static table view cells, general tint color and so on. [UIStoryboard -instantiateViewControllerWithIdentifier:] is the method you might find interesting.
But I'd rather recommend you to check out the UIPageViewController, it's like a container for the screens. Unfortunately, it cannot have the segues to your scenes (because of the special way segues work) so you have to use -instantiateViewControllerWithIdentifier: method anyway. You can treat inner view controllers of UIPageViewController as you do with rootViewController before.
You can also navigate without segue and Its easy way I think.
If you want to navigate from Class1 to Class 2 then follow these steps.
1) In Class 1, Import Class2.
2) In your button Action, Write this code.
Class2 *next = [self.storyboard instantiateViewControllerWithIdentifier:#"Class2 Identifier name"];
[self.navigationController pushViewController:next animated:YES];
Do not forget to give Identifier name in story board that is "Storyboard ID" in Attribute inspector of particular class.
No need to add Segue,Your storyboard would look clean.
The problem is that you are adding view controller after view controller with modal presentation. That causes each view controller to be added on top of the previous one, and all of them accumulate, using more and more memory.
Using a navigation controller and a push also piles the view controllers on top of each other.
You will have this problem if you use storyboards, nibs, or create the view controllers manually.
If you have a design where the user can move through a large series of view controllers then you probably want to dismiss the previous one before pushing/presenting a new one.
You can probably dismiss the previous view controller without animation and then present the new view controller each time you want to display a new one and avoid the memory issue. i'd have to experiment with it to get the effect I was after, but that's what I would suggest.
My project contains over 60 View Controllers and Xcode is very laggy when loading the storyboard.
How can I resolve this without switching to xibs? I am using Xcode 5.1 and iOS 7.x
Problem
Putting all of your ViewControllers in one Storyboard will significantly slow down Xcode (which renders XML to show your ViewControllers) if the number of the ViewControllers is above 10. Storyboard is not the place to put all of your views, because as its name suggests a board of a specific story.
Solution
Make multiple Storyboards with 5 or 6 ViewControllers each, where you can avoid rendering hell of multiple ViewControllers. You can divide your Application on different boards named by group functionality like LoginStoryboard, UserProfileStoryboard, etc.
You can instantiate a storyboard and present a specific controller by the code below:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Your Storyboard Name" bundle:nil];
UIViewController *viewController = [storyBoard instantiateViewControllerWithIdentifier:#"Your Controller ID"];
[self presentViewController:viewController animated:true completion:nil];
Keep views in more than one storyboard. It's not the problem if not every controllers are connected with segues. There is no good way to keep a large number of views in a storyboard, in addition to working on a better computer.
Im having some trouble with a view that I needed instantiating from a storyboard ID. In IOS simulator, the view loads with everything in place but is completely unresponsive. The date picker doesn't move and the buttons don't accept any interaction.
Ive checked the 'custom class' matches in IB and the Storyboard ID matches. The code is being executed in the PickerViewController because the UIDatePicker is being created in code and is correct and present in IOS simulator. Its just that nothing accepts any interaction. The buttons don't even go blue when touched.
I created the view in the previous view controller with:
PickerViewController *addViewController = (PickerViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"view"];
[addViewController.view setUserInteractionEnabled:TRUE];//chucked this line in to see if it helped
[addViewController setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:addViewController animated:YES completion:NULL];
I'm not sure if this is a code problem, or if I've not hooked something up in IB properly. Any ideas??!!
Check your view controllers class in assistant editor:
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.
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