My app has a login view, a loading view,a split view, and a menu view.
On launch, the initial view is the login view. It proceeds to the loading view when the user logs in successfully. Once the data is loaded, I present the split view. On the split view, I have a menu that I present modally. Among the options for the menu is logout. When the user logs out, I want to return to the login view. So far, so good.
The problem is that when I check the view hierarchy, the split view is still beneath the login view. Theoretically, the user could create a situation with an infinite number of layered views in this way.
How can I get the user back to the login view and dismiss the split view?
I am using storyboards and segues to get to the split view. The login view pushes to the loading view which pushes to the split view. I present the modal menu in a custom modal presentation controller.
//VC1
-(IBAction)button_click:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController2 *viewController2 = [storyboard instantiateViewControllerWithIdentifier:#"VC2"];
[self.navigationController pushViewController:viewController2 animated:YES];
}
//VC2
-(IBAction)button_click:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController3 *viewController3 = [storyboard instantiateViewControllerWithIdentifier:#"VC3"];
[self.navigationController pushViewController:viewController3 animated:YES];
}
//VC3
// In .h file
#interface ViewController3 : UIViewController<ViewController4Delegate>
-(IBAction)button_click:(id)sender;
#end
//In .m file
-(IBAction)button_click:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController4 *viewController4 = [storyboard instantiateViewControllerWithIdentifier:#"VC4"];
viewController4.delegate=self;
[self.navigationController presentViewController:viewController4 animated:YES completion:nil];
}
-(void)completed
{
[self.navigationController popToRootViewControllerAnimated:YES];
[self.parentViewController.parentViewController dismissViewControllerAnimated:YES completion:nil];
}
//VC4
//In .h file
#protocol ViewController4Delegate
-(void)completed;
#end
#interface ViewController4 : UIViewController
-(IBAction)button_click:(id)sender;
#property(nonatomic,weak) id <ViewController4Delegate> delegate
//In.m file
-(IBAction)button_click:(id)sender
{
[self dismissViewControllerAnimated:NO completion:^{
if(delegate)
{
[delegate completed];
}
}];
}
Do you have a navigation controller for this ViewController Hierarchy? Assuming you do have a navigation controller:
If the LoginView is set as the rootViewController for the Navigation Controller and the LoadingView and SplitView are "pushed" onto the Navigation Stack, then what you can do is you can dismiss the modal and in the completion block, you can pop to the root view controller -> which would be your Login Controller.
So in your LogoutModal you would do this on the Logout Button Click Handler:
[self.presentingViewController dismissViewControllerAnimated:YES completion:^{
[self.presentingViewController.navigationController popToRootViewControllerAnimated:YES];
}];
This dismisses the modal and then as soon as that is complete, it pops the navigation stack all the way back to the root view controller.
Related
I have created storyboard which I want to open on top of another view or in childView so that when I close or destroy this view of storyboard the earlier view on which the storyboard is opened remains the same.
When I run the following code:-
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"neolick"];
[[UIApplication sharedApplication].keyWindow setRootViewController:detailViewController];
First, the storyboard opens but I don't know whether it opens on top of previous view or it destroys the previous view & then open.
Second, the functions needed on that storyboard runs automatically which is as I want but how these things are working.
If anyone can help me understand the above code and its working.
NOTE: I cannot call the earlier view again in same state because of some reason.
Thanks in Advance!!
Here you are setting root view controller
it will not keep your back screen as it is what you want
If you want to keep current screen and show other screen on that
you have two approaches
1) Present ViewController
2) Push View Controller
1) Present ViewController
for this you can present your screen on top of other screen which is visible
for example
- (IBAction)btnNextTapped:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"neolick"];
[self presentViewController:detailViewController animated:true completion:nil]
}
2) Push View Controller
For that you need NavigationController and need to push your ViewController from current visible screen
i.e
[self.navigationController pushViewController:vc animated:true];
EDIT
as per discussion you need to find current top view controller then you should present it
Add this method below your method
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
And Replace this method with code
- (void)goToNewPage:(CDVInvokedUrlCommand*)command
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"neolick"];
[[self topMostController] presentViewController:detailViewController animated:true completion:nil];
}
I added one ViewController to my project and created one class.
After I bind this class to my ViewController.
In another controller I have method:
- (IBAction)login:(id)sender {
// How here I can do redirect to controllerViewController
}
There are two ways to push view controllers in the application.
1) by Segue
2) By View controller identifier
1) By Segue :
[self performSegueWithIdentifier:"SegueIdentifier" sender:self];
2) By View controller identifier :
Yourclassname *gotoYourClass = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerIdentifier"];
[self.navigationController pushViewController:gotoYourClass animated:YES];
- (IBAction)login:(id)sender {
ViewController *vc = [[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self presentViewController:vc animated:YES completion:nil]; }
In the storyboard give your view controller an identifier (under the Attributes Inspector) then use the following code, to bring that view forward.
IF YOU WANT TO USE PUSH THEN USE THIS CODE
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"STORYBOARDNAME" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"VIEWCONTROLLERIDENTIFIER"];
[self.navigationController pushViewController:vc animeted:YES];
IF YOU WANT TO PRESENT THEN USE THIS CODE
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"STORYBOARDNAME" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"VIEWCONTROLLERIDENTIFIER"];
[self presentModalViewController:vc animated:YES];
Note: In UIViewController please enter your view controller name which you want to push into another view.
If you want to comeback to the current ViewController later then use Navigation ViewController or else just use the presentedViewController of self(your current viewController)- no going back business, like they have previously illustrated.
For a simple block of execution(demo or practice) it's all the same but for a project application it completely matters to make the correct choice.
In my app after pressing the login button in my loginViewController, it push to front viewController of my SWRevealViewController. In my RearViewController I have the sign out button. When I press it it should pop to the back viewController again (LoginViewController). But even though I set the button click event like this it doesnt navigate to the loginViewController.
-(void)signOutClick :(id)sender
{
[self performSelectorInBackground:#selector(moveToLoginView) withObject:nil];
}
-(void)moveToLoginView
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
But when I swipe the view it gose to the back view.I want to disable that swipe feature to the back view. And I want to go to the back view when click on the sign out button in my RearViewController. How can I do that? Please help me.
Thanks
I am not sure but instead of using
[self.navigationController popToRootViewControllerAnimated:YES];
try using,
[self.navigationController popViewControllerAnimated:YES];
And to stop swipe gesture you can use code like,
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.revealViewController.panGestureRecognizer.enabled = NO;
}
You need to reset the top view controller if you want to perform these kind of actions off of a click. E.g.
get an instance of the ECSlidingViewController
ECSlidingViewController *slidingController = self.slidingViewController;
get the view controller you wish to be on the top
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"mainViewController"];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
set the topViewController property
slidingController.topViewController = nc;
[slidingController resetTopViewAnimated:NO];
I am tring to show UIViewController which is inside the UIStoryboard. There isn't any problem about poping up the view. But the navigation is not working in the popup viewcontroller; such as when I touch back button
[self.navigationController popViewControllerAnimated:YES];
I am using that code in AppDelegate --> didReceiveRemoteNotification method
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
PFProfileInfoVC *viewcontroller = [mystoryboard instantiateViewControllerWithIdentifier:#"SBID_ProfileVC"];
viewcontroller.strAuthorID = [userInfo objectForKey:#"aps"][#"targetId"];
[self.window.rootViewController presentViewController:viewcontroller animated:YES completion:nil];
Thanks,
When you use presentViewController, the viewController is not pushed onto the navigation stack. Normally, it is presented modally. So if you want to dismiss it, use
[self dismissViewControllerAnimated:true completion:nil];
segues not working after going to destination view controller (which is in storyboard )programmatically from a button click of view controller (which is not in storyboard)
- (IBAction)OK:(id)sender {
UIStoryboard *myStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
mainViewController *controller = (mainViewController *)[myStoryboard instantiateViewControllerWithIdentifier:#"mainViewController"];
[controller setModalPresentationStyle: UIModalPresentationFormSheet];
[self presentModalViewController:controller animated:YES];
}
Okey, if i am not wrong, i think , the button click segue is using navigationcontroller , if so , watch your custom segue ,
[self presentModalViewController:controller animated:YES];
you are making an model segue, so your navigation controller will be unknown after the segue is done.