Move to navigation controller from swrevealcontroller? - ios

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];

Related

SWReveal ordinary push with back

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];

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

How to show/push a navigation controller programatically

Using a storyboard, I can have a controller have a show/push segue to a navigation controller. The new navigation controller then will have the navigationController set to the existing navigation controller and the view controllers of the new navigation controller will have the new navigation controller as their navigation controllers. If I try programmatically pushing a navigation controller it fails though. Is there any programatic way of modifying the view controllers of a navigation controller so that they can contain a navigation controller? The following won't work:
let aNavigationController = UIStoryboard(name: "OurStoryBoard", bundle: nil).instantiateViewControllerWithIdentifier("OurNavigationController") as OurNavigationController
navigationController!.pushViewControll(aNavigationController, animated: true)
NavigationControllers do not push each other. You can replace a NavigationController with another one, but that will not involve a "pushing" animation.
You can, however, set different view controllers on the same Navigation Controller and have an animation. These will replace the existing view controllers inside the Navigation Controller. Here's an example to push one View Controller and replace any existing view controllers inside the navigation controller:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ViewControllerOne *vc1 = [storyboard instantiateViewControllerWithIdentifier:#"ViewControllerOne"];
NSMutableArray *controllers = [NSMutableArray array];
[controllers addObject:vc1];
[yourAppNavigationController setViewControllers:controllers animated:YES];
If you want to replace the current view controller(s) with multiple view controllers:
// 1.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
FirstViewController *vc1 = [storyboard instantiateViewControllerWithIdentifier:#"FirstViewController"];
SecondViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
ThirdViewController *vc3 = [storyboard instantiateViewControllerWithIdentifier:#"ThirdViewController"];
// 2.
NSMutableArray *controllers = [NSMutableArray array];
[controllers addObject:vc1];
[controllers addObject:vc2];
[controllers addObject:vc3];
// 3.
[yourAppNavigationController setViewControllers:controllers animated:YES];
Again, this involves the "pushing" animation that you are probably looking for, and it replaces the existing view controllers so there won't be an undesired back button (in the first code example w/ one VC).

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