Using UIButtons in storyboard to navigate towards previously used Scene - ios

I am making an app in xCode using Swift, and I need help with something. How do I program a UIButton that I added on a Scene on my Storyboard to navigate towards the previously used Scene (there are more than one Scenes in my app).For Example; if Im in scene3 and I'm navigated towards the scene with the UIButton, how can I program it to take me back to scene3 instead of the main menu? Or if I were in Scene2 and was navigated to the Scene with the UIButton, and I want it to take me to Scene2 instead of Scene3 or Main Menu.
Thank you
The Blue Scenes represent the levelScenes that will lead to the redScene after the level is done, however I want the UIButton to lead back to the exact same levelScene after it is pressed

You can use:
self.dismissViewControllerAnimated(true, completion: nil)
To dismiss the current view controller from the view hierarchy.
So you would create an IBAction for your UIButton that would execute that method.

Related

UINavigationController push method load next VCs elements before animation completes

I have experienced a strange thing when I use UINavigationController with push method. Let's say we have a ViewController with two buttons (sign in & sign up). When user taps each of the buttons, the app presents the proper ViewController, but the UI elements, placed on that ViewController (for example UITextFields, Buttons) appearing first, while the transition animation still taking place.
I use a function to setup my layout in each ViewController and I'm not dealing with Storyboard.
I tried to use viewWillLayoutSubviews(), viewWillAppear(), etc, but experienced the same thing...
How can I reach smooth transition between the views?
Finally I solved it. The overlapping Viewcontroller did not have background color defined.

Segue only working once?

Hi I made a game using SpriteKit and wanted to add a leaderboard using a UITableView. My segues are working perfectly from my GameViewController to the TableViewController and back. However I can only do this once. Once I am back to my GameViewController, tapping the same button wont take me to the TableViewController for the second time. Why is this happening?
I set it up so when a certain SKSpriteNode is tapped it segues to the the TableViewController. Currently I am using this line of code to segue from the GameViewController to the TableViewController (This code is within GameScene.swift)
self.view!.window!.rootViewController!.performSegueWithIdentifier("showScores", sender: self)
I then setup a Back button within a navigation bar and created a segue back to the GameViewController (by dragging the BarButtonItem to the GameViewController and selecting presentModally). Some help would be appreciated. Thanks!
I think you are segueing to the leaderboard, segueing back, but in the process adding the main game view to the stack rather than removing the leaderboard, so when you try to segue again, it is not the visible game scene that receives the call.
Try using this rather than a segue in your leaderboard code (where you ask to segue back to the game scene):
self.dismissViewControllerAnimated(true, completion: nil)
If that doesn't work use a delegate to ask the game scene to dismiss the leaderboard.
Edit: I was rambling and maxed out my word count for the comment, so thought I'd add my explanation here!
Think of the stack as a pile of paper, where each piece of paper is a viewController, the topmost piece being the one that's visible (naturally). When you segue or present a viewController modally you are adding a viewController to the stack or 'adding a piece of paper to your pile'. It is generally then a bad idea to segue to and from like you were doing because you are adding more and more 'pieces of paper' to the stack. You tend to get memory problems and/or irritating bugs :P. Instead what is considered best practice for programmatically going back is to do one of two things: if you are using a navigationController you should call popViewControllerAnimated, or if you aren't, like in this case, you should use dismissViewControllerAnimated. Both these functions take the topmost 'piece of paper' off the stack entirely. Fixing that problem of continually adding the viewControllers to the stack. If any of that was confusing (I'm writing this on my phone so could be!) just send me a comment or a message and I'll try to explain better! :)

Swift: Seeking advice on accomplishing specific flow between storyboards/viewcontrollers

So I am working on an app and am finally getting to a point where I am starting to build actual modules instead of playgrounds and utility apps for tests. So I really want to do this right since I am jumping into the real deal right now. I was hoping to get advice that will help me accomplish my goals for the apps "flow" without me hacking something together that will come back to bite me later.
So imagine I have a home screen(a single view controller) that can branch to multiple storyboards. The mechanism I want to trigger transitions is the user grabbing an image on the home screen with their finger, and flicking it off the screen. When the image is no longer on screen, I'd like to transition to a storyboard that corresponds to that image. For instance, the user might flick the "settings" image to open a settings panel.
[home storyboard] -- [user flicks image off screen] --> [alternate storyboard]
I have already accomplished this kind of, but with the way I am doing it now I am unsure how to be able to navigate back from the second storyboard back to the home storyboard. It also seems unclean and hacky to me.
Right now it is set up as such:
Home is its own storyboard - main.storyboard
Home contains one simple viewcontroller
Alt is another storyboard - alt.storyboard
Alt contains a navigationcontroller
How can I facilitate things such that Alt's navigation controller will recognize that it was just in the Home storyboard, so that it will provide a "back" button for navigating back home?
Or, if anyone has any advice as to how I might accomplish this in a neater way, I would greatly appreciate it. I want each "module" (ie alt.storyboard's contents) to be in different storyboards for organizational sake.
Here is the code I use to seque to my second storyboard:
if !(recognizer.view!.window == nil) {
print("object left window")
let viewController: UIViewController = (self.storyboard?.instantiateViewControllerWithIdentifier("Alt"))! as UIViewController
self.presentViewController(viewController, animated: true, completion: nil)
}
Thanks so much for taking the time to check this out, let me know if I have not been clear enough.
you could put the main viewcontroller (from Home storyboard) itself into a navigation controller and simply push the initial viewcontroller from the storyboard you want to reach (in your example Alt storyboard) with a custom transition. so the viewcontrollers from all the other storyboards except of Home should not be embedded in a navigation controller!

Completely remove View Controller - Swift

I created a little game (not with Sprite Kit), I have a MenuViewController and a GameViewController.
On my GameViewController, I have a button "MENU" to go to the menu. I had this code to the GameViewController :
print("test")
It is executed every seconds with using a timer.
When I press the "MENU" button, I find myself on the menu but the timer is still running. I think the GameViewController is not completely removed, how can I do this ?
PS: to dismiss the GameViewController, I use this :
func goToMenuViewController() {
let menuViewController = MenuViewController()
menuViewController.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
self.presentViewController(menuViewController, animated: true, completion: nil)
}
EDIT 1
I add some infos about my app hierarchy :
When the user launch the app, he finds himself on the MenuViewController.
There is a play button on this ViewController which takes to the GameViewController.
On the MenuViewController, there is an other button which takes to the RulesEditorViewController, allowing to modify rules displayed on the GameViewController
you can not see if the GameViewController is removed in this way.
if you use a timer in a GameViewController, it will keep a ref to GameViewController until it stop executing.
By the way, present menu view controller won't make the game view controller be removed
Your try to dismiss GameViewController is wrong. You are create new Menu controller and showing it above the GameViewController. That's why this controller is still in app memory.
You have to use this function self.dismissViewControllerAnimated(true, completion: nil) or self.navigationController?.popToRootViewControllerAnimated(true) depending on your segue type.
For now if you want access RulesEditorViewController you have to stop the game and leave this controller. But if you want modify options while playing then it will be better if you will access RulesEditorViewController directly from your GameViewController like you trying to show Menu now.
Update:
First of all you should understand view controllers hierarchy and ways how to present it. I believe this tutorial on example of storyboards will help you: http://www.raywenderlich.com/50308/storyboards-tutorial-in-ios-7-part-1

correcting navigation between VCs in existing app

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.

Resources