SWReveal ordinary push with back - ios

I have storyboard structure with SWRevealViewController. Everything works fine, setting view controllers etc. Now, I have one image on menu that leads to profile and is not in structure of SWReveal. Anybody knows any way of pushing it to root navigation controller and back button to lead back to SWReveal?
I have tried this:
RegistrationvViewController *vcSw = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"editProfile"];
[self presentViewController:vcSw animated:YES completion:nil];
I embedded SWReveal in NavigationController and tried performingSegueWithIdentifier but back is not shown as well.

//if you want to push from swreveal to any controller so you have to make a navigation controller
use this code
UIStoryboard*Storyboard=[AppDelegate storyBoardType];
yourController *dashboard=(yourController*)[Storyboard instantiateViewControllerWithIdentifier:#"yourControllerId"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:dashboard];
[navController setViewControllers: #[yourController] animated: YES];
[self.revealViewController setFrontViewController:navController];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
//back to the swreveal from controller
[self.revealViewController revealToggleAnimated:YES];

Related

Move to navigation controller from swrevealcontroller?

I have used SWRevealController in my app.On click of item in UITableView I want to go to a navigation controller so that I can switch between multiple view controllers.But as of now I am not able to redirect to navigation controller.I have used below code but it just replace the controller.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MoreHelpController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"HelpController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[navController setViewControllers: #[rootViewController] animated: YES];
[self.revealViewController setFrontViewController:navController];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
Please tell how can I directly go to navigation controller.It is very confusing here.
You just cannot move to navigation controller. Navigation Controller takes you to another view controller from one view controller.
If you want to move to another view controller on selection of table view row, then use didSelectRowAtIndexPath method of tableview and inside that use this:
yourViewController *obj = [self.storyboard instantiateViewControllerWithIdentifier:#"yourViewControllerIdentifier"];
[self.navigationController pushViewController:obj animated:YES];

Calling pushViewController after a presentViewController does not work

I am presenting my view controller like this -
[self.navigationController presentViewController:self.thingContainerViewController animated:YES completion:nil]; //self.navigationController not nil here
This shows a UITableView. I want to push a VC on the navigation stack from here. But the self.navigationController is nil at this point. Any idea how to make this work?
[self.navigationController pushViewController:otherContainer animated:YES]; //self.navigationController is nil at this point
You need to wrap the view controller you are presenting in a navigation controller in order to be able to use the push and pop methods.
So for the first step:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.thingContainerViewController];
Then:
[self.navigationController presentViewController:navigationController animated:YES completion:nil];
If you do that, your code will work.
Swift 3/Swift 4
first of all you need to set navigation controller on which you want to present.After that do navigation process on your second view controller.
Example like that
let firstPresentVC = FirstVC(nibName:"FirstVC",bundle:nil)
let navVC = UINavigationController(rootViewController:firstPresentVC)
navVC.isNavigationBarHidden = true
self.present(navVC, animated: true, completion:nil)
Now You are on Present Stack With Navigation
You can push after that
let secondPushVC = secondPushVC(nibName:"secondPushVC",bundle:nil)
self.navigationController?.pushViewController(secondPushVC, animated: true)
UIViewController.navigationController means:
The nearest ancestor in the view controller hierarchy that is a navigation controller.
on the other hand, presentViewController makes new view controller out of hierarchy, the new view controller has no navigation controller ancestor unless you assign one to it by [[UINavigationController alloc] initWithRootViewController:self.thingContainerViewController] as #Dima mensioned.
so, the solution is
UINavigationController *targetVCWithNavigationControllerAncestor = [[UINavigationController alloc] initWithRootViewController:self.thingContainerViewController];
[self.navigationController presentViewController:targetVCWithNavigationControllerAncestor animated:YES completion:nil];
then you can push new view controller from self.thingContainerViewController

SWRevealViewController - push view controller from side menu

I've set up my app using the SWRevealViewController and it's working fine but I want to change how it works. At the moment I have the following views on the same level:
Home
View A
View B
But I want:
Home
View A
View B
I still want Home, View A, View B to be in the menu but when clicking on View A or View B it gets pushed onto Home. And in the navigation bar it has a back button instead of the menu button.
Is this possible using SWRevealViewController?
in objective-C
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
SWRevealViewController *main = (SWRevealViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"SWRevealViewController"];
[self presentViewController:main animated:YES completion:nil];
in swift -- it automatically open the your root view controller of SWL
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let main = storyboard.instantiateViewControllerWithIdentifier("SWRevealViewController") as! UIViewController //SWRevealViewController
self.presentViewController(main, animated: true, completion: nil)
I found an answer and hopefully it helps someone reading this. It has both ways, SideMenu when you have a tabBarController or only a NavigationController. Posting snippet from answer, which worked for me.
With TabBar Controller:
UITabBarController *tbc = (UITabBarController *)self.revealViewController.frontViewController;
UINavigationController *nc = tbc.selectedViewController;
[nc pushViewController:myVC animated:NO];
[self.revealViewController setFrontViewPosition:FrontViewPositionLeft animated:YES];
With Navigation Controller:
UINavigationController *frontVC = (UINavigationController *)self.revealViewController.frontViewController;
[frontVC pushViewController: yourVC animated:NO];
[self.revealViewController pushFrontViewController:frontVC animated:YES];

performSegueWithIdentifier without storyboard idendentifier

I've a UITableViewController with dynamics rows, for every row, I need to open a new viewcontroller.
I've tried to use performSegueWithIdentifier, but it doesn't works because I don't have storyboard identifier.
How to open a new viewcontroller dynamically?
I've tried with:
newUiViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"controller"];
[self.navigationController pushViewController:controller animated:YES];
but it doesn't work.
You should give a controller identifier in your storyboard, check this:
Class is your "newUiViewController" and Storyboard ID "menu" is your "controller"
then you can do:
newUiViewController *controller = (newUiViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"controller"];
[self.navigationController pushViewController:controller animated:YES];
Ok, I've found the solution.
Like navcontroller I'm using "SWRevealViewController", so the correct code is:
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: #[list] animated: YES];
[self.revealViewController setFrontViewController:navController];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
I think that is useful for other

SWRevealViewController - manually switch to another view?

I have a sidebar menu, made with SWRevealViewController.
One of menu elements in sidebar is "sign-in". It opens sign-in view (via custom SWRevealViewController segue).
I want to programmatically switch to another view after user successfully signs in. How do I do that?
UPDATE, my code:
ViewController *vc = [[ViewController alloc] init]; // this is main front ViewController
SWRevealViewController *revealController = self.revealViewController;
[revealController setFrontViewController:vc animated:YES];
After this I get just empty screen. What am I doing wrong? I feel that this is wrong:
ViewController *vc = [[ViewController alloc] init];
so what is correct way to access already loaded view controller? (it loads at app start by SWRevealViewController as front controller)
Try this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SecondViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[navController setViewControllers: #[rootViewController] animated: YES];
[self.revealViewController setFrontViewController:navController];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
work for me :-)
Use
- (void)setFrontViewController:(UIViewController *)frontViewController animated:(BOOL)animated; method
SWRevealController has it's own property you can access from any UIViewController:
SWRevealViewController *revealController = self.revealViewController;
You can check example projects at it's GitHub repository:
https://github.com/John-Lluch/SWRevealViewController
Here is a Swift version of the setFrontViewController solution:
if let secondViewController = self.storyboard?.instantiateViewControllerWithIdentifier("SecondViewControllerStoryBoardID") as? SecondViewController {
let navController = UINavigationController(rootViewController: secondViewController)
navController.setViewControllers([secondViewController], animated:true)
self.revealViewController().setFrontViewController(navController, animated: true)
}
Try this:
ViewController *vc = [[ViewController alloc] init]; // this is main front ViewController
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: #[vc] animated: YES];
// [navController pushViewController:vc animated:YES]; // use this if you want to stack the views
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
There is a new API - (void)pushFrontViewController:(UIViewController *)frontViewController animated:(BOOL)animated;
As far as I know, this is the most elegant way that animates correctly to switch between view controllers manually.
// get the view controller you want to push to properly.
// in this case, I get it from Main.storyboard
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController * vc = [sb instantiateViewControllerWithIdentifier:#"SignInViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc];
[navController setViewControllers: #[vc] animated:NO];
[self.revealViewController pushFrontViewController:navController animated:YES];
If you are in the target vc that doesn't import SWRevealViewController and want to push back:
// get your vc properly
[self.navigationController setViewControllers:#[vc] animated:YES];
Please notice that [self.navigationController showViewController:vc sender:self]; has the same result, but don't use this since this creates a new view controller on the navigation stack, which is basically meaningless while using SWRevealViewController.
This one works for me perfectly
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
UINavigationController *navController = [storyboard instantiateViewControllerWithIdentifier:#"NavController"];
[navController setViewControllers: #[rootViewController] animated: YES];
[self.revealViewController setFrontViewController:navController];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
#Evana has a good answer, however for my case which passing parameter to the destViewController, I need to improve it as below. By following her example exactly, I noticed the DestViewController viewDidLoad was called twice. First with 0 on the 'selectedId', only the second call did the 'selectedId' is receiving my tag value.
Thus, in order for a cleaner navigation, the DestViewController must be obtained from the navController, so that there is no redundant call.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *navController = [storyboard instantiateViewControllerWithIdentifier:#"DestNavController"];
DestViewController *destViewController = (DestViewController*)[[navController viewControllers] objectAtIndex:0];
destViewController.selectedId = ((UIButton*)sender).tag;
[self.revealViewController setFrontViewController:navController];

Resources