Transition from modal view to next view controller in modal's parent - iphone

I have MyViewControllerA which was pushed into view by a navigation controller. MyViewControllerA displays MyModalViewController. MyModalViewController has a button where once pressed will push MyViewControllerB ontop of MyViewControllerA. I created a delegate so MyModalViewController can tell MyViewControllerA that a button was a pressed so MyViewControllerA can place MyViewControllerB ontop of it.
Is there a clean way to transition from MyModalViewController to MyViewControllerB. I tried to dismiss the modal view after pushing MyViewControllerB, but it does not give me that smooth animation when you normally drill down with a nav controller.

As you said you have delegate that can tell ControllerA about the button press. Now what you have to do is have a flag in ControllerA (which will we use to tell A about the button press):
Initially set this flag false (in viewDidLoad).
Write pushController code for B in A's viewWillAppear method with checking:
if(flag)
push B.
When you press the button in modalViewController set this flag and dismiss that.
When this view will be dismissed then your viewWillAppear method will be called and it will push B if flag is set.
If still animation is not smooth then please use viewDidAppear method rather than viewWillAppear.
Thanks.

Related

If "setNavigationBarHidden:YES", then how to come back to previous controller?

I don't want to let the navigation controller show its navigation bar in the whole project.
Now there are three view controllers
(1) Login view controller
(2) Sign up view controller
(3) Home view controller.
I just hope to use action(which can be triggered by any kind of event, i.e. drag gesture, not necessary the pressing button) to switch between these view controllers. But I found once I get to the "signup view controllers", I can not go back to the login view controller, since there is no "BACK" navigation bar.
Questions:
How "PUSH" in one view controller, then "POP" in the other view controller?
Or there is some different way to solve this problem?
Thank you so much, any suggestion is great.
To programmaticaly go backward in a navigation controller's navigation stack, call this method:
[self popViewControllerAnimated:YES];
When and where you call this is up to how you want your app to flow. Essentially, the default navigation controller calls this automatically when the navbar's back button is pressed. But if you hide the navbar and still need to pop back, you can call this method to pop back.
As for pushing forward, it's simply a matter of creating a Push segue on the storyboard, giving it a name, and then in your code, call this method:
[self performSegueWithIdentifier:#"segue_YOUR_SEGUE_ID" sender:self];
On the question of your app, what probably makes most sense is for the login view be a view by itself. It should contain a modal segue to a sign up view for new users as well as a modal segue to the home view controller (which may or may not need to be embedded in a navigation controller).
Performing a modal segue works exactly the same as a push segue (if you're using storyboards. Hook up the segue, choose a modal segue, then call the performSegueWithIdentifier: method in your code when you need the segue to occur.
Dismissing a modal view is slightly different, but still quite simple. It goes like this:
[self dismissViewControllerAnimated:YES completion:nil];
It's fairly check to do with an 'if' statement...
if (self.navigationController.navigationBarHidden == NO) {
//YOUR ACTION
}
Hope that helps!

Multiple instances of the same TabBarController after Modal Segue iOS

I have an app with one main TabBarController containing two tabs that control two different views, A & B. View A is a scrollView and View B is a TableView. When i initially load the app, the scrollview in view A is empty.
In order to add pages to my scrollView, I have set it up as follows: I go to view B and perform one modal segue to a view embedded with a navigationBar. The navigationBar only has one button, 'Cancel', which I use to dismiss the view. Otherwise, the user must click on an image an perform another modal segue to a different view. This view has no navigation bar, and has one button 'DONE', which I use to perform a modal segue back to the initial tabBarController.
Here's the problem: the page is added to the scrollView with no errors after I press 'DONE'. However, I believe I now have two instances of the same tabBarController floating around in memory. When I attempt to grab the views contained in the scrollView with a different button, it tells me that it is now empty (even though it was full during viewDidLoad and viewDidAppear).
How can I remove the initial tabBarController view or otherwise how can I segue back to the tabBarController that I have already allocated? Any help would be extremely appreciated! Thanks!
You shouldn't do a segue back to the original view controller. Rather, you should dismiss the current view controllers animated, and show your original tabBarController.
Inside the view you were segueing back from, add:
tabBarController *tabs = (tabBarController*)[[self presentingViewController]presentingViewController];
tabs.selectedViewController = [tabz.viewControllers objectAtIndex:0];
[[[self presentingViewController] presentingViewController] dismissViewControllerAnimated:YES completion:nil];
Then you will have the view A appear and still use the same allocation.

When is viewWillAppear called?

By my count, the only two instances when viewWillAppear is called is when you initialize your view controller, or when you pop off the view controller that's on top of it on the navigation stack (ie pushing the back button on the viewcontroller ahead of it). Are there any other instances when viewWillAppar is called? I don't believe it's called when the app becomes active. Interested to hear some responses on this.
viewwillappear method is called as and when the view controller's view is added to the window. ( if the view is already in the window and is hidden by another view, this method is called when the view is once again revealed). The method is a notification to the view controller that the view is about to become visible. You can override this method to make any customizations with presenting the view.
This will also be called anytime addSubView is called, with your view.

Navigation application -- Back Button

When we click on the back button on a nav view, is there any method (delegate) which gets called on current view controller before poping it out of stack and pushing next in stack?
The only method available is the viewWillDisappear and the viewDidDisappear in the viewController managed by the UINavigationController. You might be able to check the size of the UINavigationController viewController array property and compare it with the last known -count. If there are more controllers in the stack, you know that something was pushed. If there are less, something was popped.
You can hook up your own -back:(id)sender method as the selector for your back button and then do what ever you want inside that method, as long as you call:
[[self navigationController] popViewControllerAnimated:YES];

How to tell when a UIView gains focus

On the iPhone, we can simply use (void) viewDidAppear:(BOOL)animated; to perform actions when a view becomes the focus. In some events, we have a modal view with another modal view on top of it and, on the iPhone, closing the topmost modal view will fire the viewDidAppear for the lower modal view.
This is not the case for the iPad, as the view stays "visible" even though it's behind another modal view. Is there any way to tell from within a UIViewController when the view itself becomes the active view?
Can't you just use when the modal view controller's view disappears?
When the modal view's controller recieves the viewWill/DidDissapear you know that the original view is visible again.
EDIT:
in the viewDidDissapear of the modal viewcontroller add this:
[self.parentViewController viewDidAppear:animated];
This will make the viewDidAppear method be called as it is on the iPhone.
You don't need to set self.parentViewController at all, as it is done for you in the presentModalViewController method (the one your use to display the modal view controller)
try checking the value of [theUIView isFirstResponder]
it should be True for the view that has the focus of the keyboard, etc.