Let's say we have an app which has a lot of view controllers and a navigation bar. Now, the app starts with view A, then we can press next and go to B, press next and go to C etc..
Now, in the last view, let's say Z - we have a button "go to first". What I've done is, dragged from the view Z to view A and that created a segue. I gave that segue an identifier, let's say "goToA". Now, when the button is pressed I did something like
-(IBAction)goToFirstPressed{
[self performSegueWithIdentifier:#"goToA" sender:self];
}
What it does - it goes to A. But here's the important part - it doesn't go to the A that appeared on the screen for the first time, it went to another instance of view controller A. So let's say if I had in the first view controller (A) playing a video, now I go to Z then segue, I won't see that video anymore, and more important is - I can play the same video twice, overlapping the sounds.
Any idea on how to fix this? Thanks!
Segue only goes in one direction. it will always make a new instance of the view you are navigating to.
You can use delegation for that.
Try this
You can implement that protocol method like as follows:
- (void) goToFirstView{
[[self navigationController] popToRootViewControllerAnimated:YES];
}
Related
I'm trying to execute code when a button is pressed for an application but I can't find how to change the views after the code is executed. Is there a way to switch views how I want to or is there another way? Thank you in advanced, I'm very new to xcode.
edit: I'm trying to go from one view to another, not the view controller and yes I have one storyboard that I planned on using for the whole project if possible.
To execute code when a button is pressed, you have to set up a method that the button is hooked into. Because you said you're using storyboards, I'll assume your button is on the storyboard. Go to the assistant editor, hold ctrl, and click-and-drag from the button to the view controller's .m file (#implementation section). This will create an IBAction method, and any code in this method will execute whenever you press the button.
The method will look like this:
- (IBAction)aButtonPress:(id)sender {
}
According to your comments, you say you only want to change the on-screen view, and not transition from one view to the next.
Views are added and removed with the following methods:
[aSuperview addSubview:aSubview];
[aSubview removeFromSuperview];
I can't really tell you much else with a lot more detail from you... and even though I asked twice in the comments and you said you only want to change the view, not the view controller... I think you probably need to transition to a new view controller. Impossible to know for sure as you've given almost no detail...
But if you want to transition between view controllers (which also transitions views), then ...
Create two view controllers on the storyboard. Hook them together with a segue, and give that segue a name. Now, to perform that segue in code:
[self performSegueWithIdentifier:#"YOUR_SEGUE_NAME" sender:self];
I've been wrestling with this for almost 2 hours now and no luck.
I have a View Controller. Lets call it First. I press a button and it takes me to Second view controller using a modal style. In Second I add some data which I can save or discard via two navigation bar buttons: Save and Cancel. both do what they do and then they return me to the previous screen. I implemented a protocol and I use the delegate. So far everything works fine.
Today I decided to have a Third View Controller which can be accessed from the Second VC. The problem is I couldn't move to THIRD until I changed the transition from First to Second to PUSH (instead of modal). Now I can go from First to Second and from Second to Third. All good again.
THE PROBLEM : If I press Cancel or Save on the Second VC, it calls the methods, it uses the delegate to go to FIRST and execute some function but when it calls:
[self dismissViewControllerAnimated:YES completion:nil];
nothing happens and Im stuck on the Second view. Basically I was using MODAL with Delegate and protocol methods... I switched to PUSH, and I cant get rid of my Second view and return to First. It seems like the dismissViewController doesnt do anything.
Any help is greatly appreciated. I can fix all this by removing the cancel button and using the BACK which comes by default with PUSH but I just want to know what the problem is with it.. THANK YOU !!
On your 2nd viewContrller call the UINavigationController's method popViewControllerAnimated: or popToRootViewControllerAnimated:. This will pop the controller (the one calling, which is the 2nd) off the nav stack. You can get the navigation controller in a UIViewController via its property navigationController.
I am creating a project with Xcode 4.2 and using it's storyboard. In one of the views I have a button that a user will tap and it will perform some calculations. If the calculations are correct I need to display the view that they just came from. I am currently using a Navigation Controller. When the app starts it loads View 1. When I choose an option it loads View 2. If I click the 'back' button in the toolbar it loads View 1 with left animation.
In my IBAction method for the View 2 calculation I have the following snippet.
[self performSegueWithIdentifier:#"BackToView1" sender:sender];
But the problem is it loads View 1 using the left animation when I need it to load the right.
Would that be a custom segue? Am I missing something?
[Edit]
I just noticed something as well. When View 1 loads from my IBAction it appears it is initializing the AppDelegate again, whereas the 'back' button does not. I need to not initialize the AppDelegate since I am loading a data object at the start of the app. Calling init again kills my object.
You could try using the navigation controller to pop back. This will probably produce the effect you are after.
[self.navigationController popViewControllerAnimated:YES];
My app has a welcome screen that can only be shown in portrait mode. After the user has tapped through the welcome screen I'd like to show another screen that can be used in both portrait mode and landscape.
I have set up a view controller that implements shouldAutorotateToInterfaceOrientation: returning YES only for UIInterfaceOrientationPortrait, and I add the view to the window with [window addSubView:view]. I tag this view with the tag 1.
When the user taps through the welcome view and the app moves on to the new view I do:
[[window viewWithTag:1] removeFromSuperView];
[window addSubView:myViewController.view];
Where myViewController is an instance of the 2nd view's view controller (that handles the shouldAutorotateToInterfceOrientation method properly).
Now when I rotate, it still calls shouldAutorotateToInterfceOrientation on the original view's view controller, and does not call it on the new view's view controller.
This note from Apple says that only one view controller will get rotation notifications; however, I have removed the other view controller.
What am I doing wrong?
actually that note doesn't say that "only one view controller will get the notifications" but instead it says that "Only the first view controller added to UIWindow will rotate.".
So this might be the problem.
To resolve it, i would say to always have a view added to your window (call it permanent), and add your welcome screen and the next views to this permanent view.
Hope this helps.
as the note you link to state:
Only the first view controller added
to UIWindow will rotate.
So put a flag that makes sure that shouldAutorotateToInterfceOrientation returns NO until the user have dismissed the screen - and then returns YES afterwards. This is a simple and working solution - however, from a code readability point it might be confusing that a "dismissed" view actually controll the rotation.
Personally; my experience is that it's not really worthwhile having some views rotating and some don't - and users tend to don't like it.
happy coding
I wrote up a quick test that shows what you are trying to do should work. Here are the basics I did:
Create two view controllers. App starts with the first view controller being set in the AppDelegate into an instance variable viewController through NIB files. It is then added to the window as you have written.
I then setup an action that when called (could be a Timer, button on first view controller, etc.) that performed the following:
Remove view using [self.viewController removeFromSuperview]. This is different than the way you have done with the tag.
Created second view controller and assigned it to self.viewController.
Added to window like you have specified.
Not sure what is incorrect with your code. I would guess that perhaps the first view wasn't really being removed.
I am Using a Navigation based application.
However i don't want to push a view.
I have changed present ModalViewController.
Now, I am confused - how to load previouse view.
My Application's Table View - default in navigation base application
On navigation controller I have added (add employee) button.
On Add(employee) click i have written following code in appDelegate.m
-(IBAction)AddClicked:(id)sender
{
if(self.addData==nil) // addData is a object of my next view
{
addData=[[AddEmpScrn alloc] initWithNibName:#"AddEmpScrn" bundle:nil] autorelease];
}
[self.navigationController presentModalViewController:self.addData animated:YES];
}
This code works successfully & next Add Employee screen load perfactly.
But Now I am confused.
How to get back to previous view?
that is if a user click on "Save" or "Cancel"
it should display again the previous view...
main screen
I dont know how to solve it...
anybody please help me...
i will be thank full.
Have u tried using the dismissModalViewController method? should do what you are asking f or
Have you read "Using Modal View Controllers"?
If you presentModalViewController then the old view is still there "behind" it. You just need to call dismissModalViewControllerAnimated: on the original navigation controller.
If you are directly manipulating the view hierarchy by swapping out subviews, you will need to hold onto the old view in another member variable and make sure to retain it.