I have a tab bar controller that contains different ViewControllers.
One of them has a SKView and is creating a new SKScene in viewDidLoad
First time i navigate to the tab with the SKScene, it will display immediately, but every next time it will take about 2 seconds!
The strangest part is, the SKScene is totally empty! There is no nodes in it.
Every other view controller displays immediately.
What could be causing this issue?
Related
I have ViewController.swift files associated with storyboard (I use it for admob set up).
My UI is written in viewDidLoad function in each viewController class.
I have created segues in storyboard and use this code:
self.performSegueWithIdentifier("segueName", sender: nil)
Here is the problem. If I move between two screens back and forth, somehow the number of elements on the screen multiplied by two. I manage to find this due to this error:
Attempt to present VIEWCONTROLLER1 on VIEWCONTROLLER2 whose view is not in
the window hierarchy!
First time I back to the screen there is only one error. Next - 2, 4... Soon enough (back and forth between screens) delay becomes incredibly long like 15 seconds and doubles with each transition.
What is the problem and how to work around? Every time I move to the next screen remove all subviews on the previous?
The problem is you're recreating each VC each time you segue. From VC2, you need to call:
self.unwindForSegue("segueName", towardsViewController: FirstVC)
See also: UnwindForSegue
I have 2 viewControllers. One of them is for the game screen and it has lots of different variables like labels,buttons,images. The other one is for the pause menu. When i pause the game and tap the resume button, it calls the viewDidLoad of the first viewController naturally.
I want to save the last state of the game when user tap the pause button. Or i want to see the last state of the game when user tap the resume button. I don't want to use nsuserdefault for this,if there is a different solution. Hope i can explain my problem.
Best Regards,
Taha
When i pause the game and tap the resume button, it calls the viewDidLoad of the first viewController naturally
Then you're doing this wrong. There is no reason why the first view controller (with the game screen) should be torn down merely because you are showing the pause menu view controller. You need to rethink your architecture here.
For example, if the first view controller presents the second view controller, then the second view controller's view appears, but the first view controller is not torn down. When the second view controller vanishes again (resume), the first view controller's viewWillAppear: and viewDidAppear: will be called, but not viewDidLoad. Your job is to organize your tasks so that the game pauses on viewWillDisappear: and resumes on viewDidAppear: but the data displayed is not torn down or reset.
I've been working on this project for quite some time and I'm almost finished fixing up everything except one thing: memory leaks from viewcontrollers.
Here is my situation : I start in the main root view controller and navigate through VC's(root -> Levels -> Level1) like this
Level1* level1 = [self.storyboard instantiateViewControllerWithIdentifier:#"Level1"];
[self presentViewController:level1 animated:YES completion:nil];
This works fine and all but when I use this way to switch between 2 VC's multiple times, I create the new VC every time and the initial one does not get destroyed.
For example, I'm in level1 VC, decide to go to Upgrades VC, therefore using the methods from above. In my hierarchy of VC's, level1 is still alive when I'm in Upgrades scene. When I go back to the level1 scene, a new one is created with the old one still alive!
Now repeat this process several times and I can find myself with quite a few scenes of level1 VC and Upgrades VC stacked up because the initial VC doesn't get destroyed.
I thought of 2 fixes to this problem: Either I somehow destroy old VC's, which I don't know how, or use a navigation controller, which I don't know how either. I'd really prefer to do it the first way, because with a navigation controller, I fear I have to change quite a lot of stuff on how I navigate through controllers.
What I tried:
[self removeFromParentViewController];
Didn't do anything. I also tried to point the old view to nil( and all properties) once the new view was up, but this did nothing either. My VC's are still alive. If I try to point the view to nil before presenting the new VC, then I get this and a black screen :
Warning: Attempt to present on whose view is not in the window hierarchy!
Edit: I forgot to mention, I'm using ARC so I can't just dealloc stuff and all my views and VC's are done through coding, nothing in storyboard except for 2 things: In the storyboard, I put the VC in landscape mode, what class it inherits from and its storyboard ID
So almost 70 apps later I am trying out storyboards for the first time...
I think I got the basic flow working, having a nav controller stack with segues pushing or modally displaying the next scenes, and unwinding from those. All of this without any code, except for the unwinding.
How would I make a splash screen (after Default*.png) that automatically transitions to the next scene after 5 seconds? (preferrably as much done in Interface Builder as possible)
Set up your scenes and define your segues between them via the storyboard
In each view controller, set up an NSTimer to call the following method after 5 seconds:
-(void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender
I have a fairly simple app thats a game for small children. There is a main screen and 5 separate levels. 3 of the 5 levels are made up of more than one VC where actions take place in the first VC in that row then code calls a modal segue to the next one in the line and so on till it reaches the end of the row and a modal segue is called linking back to the main screen. The levels that have only one VC just perform actions then segue back to the main VC.
Every segue in the app in modal.
Also every page (VC) has a home button that will segue to the main page if pressed
I set this all up in the StoryBoard and visually everything works as Id expect but when adding sound I realized that there seems to be a major problem.
If I now understand correctly (and maybe I dont) modal segues dont actually replace the current VC with the newly requested one but rather slide the newly requested one over top the original and make it the visible display.
Currently I go from main to level 1. Level 1 does some stuff and plays some sounds that repeat via a timer. If I segue back to main visually everything is fine except the sounds being played by the timers in level 1 VC continue to play and xCdoe give me the following error quite a few times
2013-01-21 22:16:07.901 TTBetaDev[678:c07] Warning: Attempt to present <MainMenuViewController: 0x7e02f40> on <BonusViewController: 0x7ecbfa0> whose view is not in the window hierarchy!
Below is a screenshot of my storyboard in case I havent explained the layout well enough.
How should this be set up to allow the navigation I would like? A what steps will I need to take to apply that to the what I already have built in the storyboards? Or will I have to re-do all my storyborad work?
I tried apples VC documentation but I couldnt understand what relates to what Im trying to do.
COuld someone please help explain this to me
You have segues going forwards AND backwards. You shouldn't do this.
e.g. Look and Main and VC 2.
You have a segue going from Main to VC 2. This means that Main will present VC 2 as a modal view controller.
When Main does this though it is still on the stack underneath VC2.
Then you have a segue from VC2 to Main. This means that VC2 will create a new Main and present it modally too. If you continue using the app you will have multiple instances of main and all the other VCs and memory consumption will rocket.
What you need to do is delete ALL the segues that go backwards. (i.e. like the one from VC2 to Main)
Then when you want to get back to main from VC2 you have to dismiss VC2.
i.e.
in Main...
//present VC2
[self performSegueWithIdentifier:#"VC2Segue" sender:nil];
//dismiss VC2
[self dismissViewController:vc2ViewControllerInstance];
or in VC2...
//dismiss VC2 from itself
[self dismissViewController:self];
The main thing though is that you can't use segues to go backwards.
TL:DR
Nothing should segue INTO Main. Any segues that go into the left hand side of main should be deleted and dealt with properly.