Use PKRevealController (Slide Menu) on existing project - ios

Before anything and everything, I know there exists a similar thread by another user, I tried the code answered in that but it didnt worked for me as my VCs and storyboard is a bit different, thus asking same question with my setup and parameters
My storyboard and app looks like this, my initial rootViewController as a tabBarController.
I am using this PKRevealController to add a slider left menu bar
https://github.com/pkluz/PKRevealController/blob/master/Documentation/USAGE.md
I added the following code (taken from the answer on similar question I found on SO) to my appDelegate's didFinishLaunchingWithOptions method
PKRevealController *revealController = (PKRevealController *)self.window.rootViewController;
UIViewController *leftViewController = [[GDmenuViewController alloc] init];
UIViewController *frontViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"tabBarCtrl"];
[revealController setLeftViewController:leftViewController];
[revealController setFrontViewController:frontViewController];
GDmenuViewController is the UITableViewController class I made for my UITableView menu to use on left
tabBarCtrl is the StoryBoardID for the tabBarController I set
Upon compilation I am getting the following error
2014-03-16 18:18:06.659[3595:70b] -[UITabBarController setLeftViewController:]: unrecognized selector sent to instance 0xcf565a0
2014-03-16 18:18:06.662[3595:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITabBarController setLeftViewController:]: unrecognized selector sent to instance 0xcf565a0'
--------Update-------------
I changed the code in app delegate to the following since my tabBarController was my initialVC
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
GDmenuViewController *leftViewController = [tabBarController.storyboard instantiateViewControllerWithIdentifier:#"leftMenu"];
PKRevealController *revealController = [PKRevealController revealControllerWithFrontViewController:tabBarController leftViewController:leftViewController];
self.window.rootViewController = revealController;
Now I am not getting that error but still my menuViewController (TableView) isnt showing up.
I can run the app and even slide to see that the PKVC is working but instead of my tableView, it just shows up a gray blank View

For anyone who comes up across similar problem, here is how I fixed and made it to work :
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
GDmenuViewController *leftViewController = [tabBarController.storyboard instantiateViewControllerWithIdentifier:#"leftMenu"];
PKRevealController *revealController = [PKRevealController revealControllerWithFrontViewController:tabBarController rightViewController:leftViewController];
self.window.rootViewController = revealController;
my TabBarController is my rootViewController as well as the entry point
my leftMenu is the swipe menu TableViewController with a custom class GDmenuViewController
PS: If the swipe works but you dont see your swiped menuVC as expected (grey in my case), check every thing in identityInspector of your menuVC, most probably problem will be there.
In my case, my cells (static) were buggy, so I had to delete all cells and readd them.

Related

Present ViewController on UISplitViewNavigator's MasterViewController

I've created a new XCode project using the SplitViewNavigator template. One of the MasterViewController's navigationItems should present a configuration ViewController (fullScreen on iPhone, popup on iPad).
This config controller has been created in a separate storyboard (Filter.storyboard).
In this storyboard I dragged a ViewController on the stage and embedded it in a Navigation Controller (Editor -> Embed In -> Navigation Controller) because the config itself consists of different screens the user can go through.
The NavigationController has been given a StoryBoard ID "FilterNavController".
I've done this several times in other applications, so this does work. Unfortunately, I can't get it working with the SplitViewNavigator template.
Here is how I try to open the filter controller once the button has been tapped, nothing special about it;
UIStoryboard *filterBoard = [UIStoryboard storyboardWithName:#"Filter" bundle:nil];
UINavigationController *filterNavController = [filterBoard instantiateViewControllerWithIdentifier:#"FilterNavController"];
UIViewController *vc = [filterNavController.viewControllers objectAtIndex:0];
[self.navigationController presentViewController:vc animated:YES completion:nil];
self is the MasterViewController.
From my uneducated point of view, I don't see any reason why this wouldn't work. As I said, it does in other (non SplitViewNavigator template) applications.
The error message I'm getting is the following:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <UINavigationController: 0x7f9bab61a700>.'
No idea what the heck is going on here but it already cost me half a day.
Interestingly, when I just create a UIViewController on the Filter.storyboard and set its StoryBoardID, the ViewController will get presented. However, I need it to be embedded in a UINavigationController.
Any help would be highly appreciated!
For the sakes of completeness, the following method works nicely for instantiating ViewControllers from a Storyboard.
Instead of creating a UINavigationController on the Storyboard, just create the ViewController(s) and embed them in a UINavigationController on code.
UIStoryboard *myBoard = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
MyViewController *menuController = [myBoard instantiateViewControllerWithIdentifier:#"MyViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myController];
[self presentViewController:navController animated:YES completion:nil];

iOS - Navigationcontroller stack issue

Getting the tabBarController from root view navigation stack. When I fetch the selectedcontroller from tabBar controller, app getting crash.
TabController *TabBar = (TabController *)viewController.navigationController.presentedViewController;
UINavigationController *selectedNCinTab = (UINavigationController *)TabBar.selectedViewController;
When execute the above line getting crash. With below reason.
-[UINavigationController selectedViewController]: unrecognized selector sent to instance 0xf4b0be0
You probably need to access navigationController.topViewController instead of presentedViewController in 1st line

use different xib items with the same UIViewController class

I have created a .xib file containing a UITabBar with 5 UITabBarItems inside. I would like 4 of the 5 tabs to link to the same UIViewController class since they have the exact same interface (only the data differentiate their looks).
Therefore it makes sense for me to instantiate my UIViewController 4 times, once per tab bar item. And then link each one of the UITabBarItems of the .xib with one instance of my UIViewController.
But I cannot figure out a way to take a reference of my xib tab bar items in my UIViewController and send the setTabBarItem message. How could I achieve that ? I was trying somehow to pass the .xib tab bar items on init (overwriting the init) but I didn't manage to reference them. I instantiate the controllers in the AppDelegate after the self.window stuff.
(If I say something weird here, not making sense with the usual iOS programming conventions, please let me know)
Use UITabBarController for this , not sure what you exactly want to do with the same UIViewController but UITabbarController will definitely work;
UITabBarController *tabBarController = [[[UITabBarController alloc] init] autorelease];
ViewController *viewController1 = [[ViewController alloc]initWithNibName:#"ViewController1"];
ViewController2 *viewController2 = [[ViewController2 alloc]initWithNibName:#"ViewController2"];
tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1,viewController1,viewController1,viewController1,viewController2,nil];
self.window.rootViewController = tabBarController;

iOS - NavigationController thinks it's getting the same controller pushed twice

I'm a bit confused about the following code. If I comment out the second statement, it successfully shows the view:
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.navController.viewControllers = [NSArray arrayWithObject:aViewController];
[delegate.navController pushViewController:aViewController animated:YES];
[aViewController release];
Otherwise, it crashes on the following:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing the same view controller instance more than once is not supported
I add a different view controller in the app delegate, but not this one. What could be making it think it's the same one?
delegate.navController.viewControllers = [NSArray arrayWithObject:aViewController];
[delegate.navController pushViewController:aViewController animated:YES];
First line set's aViewController as navController's only controller. Second line pushes aViewController to navController again so yeah, no wonder you get it twice. Depending on what you want to do, ditch one of those two lines.
If you want to set aViewController as only controller on navController, keep first line.
If you want to push aViewController as a new controller on navController, keep second line.

What is wrong with this code? Trying to load a navController onto a modal view controller

I have a UIViewcontroller that I want to push onto a UINavigationController, which in turn would push onto a modal view using presentModalViewController:animated.
Here's my code:
TargetViewController *targetViewController = [[[TargetViewController alloc] init] autorelease];
UINavigationController *targetNavController = [[[UINavigationController alloc] initWithRootViewController:targetViewController] autorelease];
[self presentModalViewController:targetNavController animated:YES];
When code is run, the modal view loads as expected, but after dismissModalViewControllerAnimated: is called, the modal view slides down and the app crashes.
I get the following error in gdb:
-[CALayer retain]: message sent to deallocated instance
First part of question: is there anything inherently wrong with the above code?
Second part: if there is nothing wrong with above code, where should I look next to debug?
Additional info:
When I don't release or autorelease the navController, it works fine. But Instruments will show abandoned memory, which I can only assume is the navController not being released. Maybe the modal view controller
P.S. I know that the crash is related to the memory management of the above ViewController, navController and modal view, because my code was working prior to messing with this code.
You generally don't push a navController as a view as the navigation controller works as the root controller. The views are pushed from the navController. Once you have a view pushed, you could then present the next view modally.
What happens if you don't use autorelease?
I.E.:
TargetViewController *targetViewController = [[TargetViewController alloc] init];
UINavigationController *targetNavController = [[UINavigationController alloc] initWithRootViewController:targetViewController];
[targetViewController release];
[self presentModalViewController:targetNavController animated:YES];
[targetNavController release];
Fixed the issue. I was releasing the VC, causing the crash. Thanks for the input.

Resources