i'm a new developper with storyboard.i try to make a app with a slide-out menu.
To do this, i use the library : SWRevealViewController and the tutorial : http://www.appcoda.com/ios-programming-sidebar-navigation-menu/ .
i follow the tutorial, but i load the application, i'have this error :
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '*** -[__NSArrayM
insertObject:atIndex:]: object cannot be nil'
my app crash on this line :
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
how can i set self.revealViewController ?
here my storyboard UPDATED:
to understand my app, startviewController is used to download and store data, after downloading, the mainViewcontroller is showed.
i want my slide out menu on my mainviewcontroller, but i cant not do.
here the code i add to my mainviewController viewdidload :
- (void)viewDidLoad
{
[super viewDidLoad];
self.contentView.autoresizesSubviews = YES;
_sharedUser = [User sharedUser];
///slide out menu
// Change button color
//SWRevealViewController *revealViewController = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:#"RevealViewController"];
_sidebarButton.tintColor = [UIColor redColor];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
//end slide out
self.contentView.backgroundColor = [UIColor cyanColor];
if (_sharedUser.tokenString) {
}
else{
[self showHomeWithoutLogginView];
}
}
I'm looking at the tutorial you are following. According to your screenshot, there are some stuff missing in your storyboard.
The RevealViewController should be connected with two controllers: a front viewController (for displaying content) and a rear viewController (for showing the navigation menu):
Credits for the image: http://www.appcoda.com/ios-programming-sidebar-navigation-menu/
Those connections (segues) should be marked as "reveal view controller" and each of them have to be named accordingly: "sw_front" and "sw_rear".
Then you have to add the menu items in the navigation menu (rear view controller) and connect each cell to the corresponding viewController, give the segues a name and mark them as a SWRevealViewController class. You may want to connect the front view controller to the viewController you want to be shown first.
I strongly suggest you make the tutorial as it is. I think I used it in the past and it worked pretty well. If you have any doubt about it don't hesitate to ask.
Best of lucks!
SOLVED
thanks to leandro !
here the code who is need in my staviewcontroller who solved my problem:
SWRevealViewController *sideBar = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:#"SWRevealViewController"];
[self.navigationController pushViewController:sideBar animated:YES];
Are you using the latest version of the SWRevealViewController? The AppCoda tutorial is outdated, and SWReveal has great sample on Git.
Check your segue identifier and class on your storyboard. Have you set sw_front and sw_rear? Also, in the latest version, your segue for setting the Menu / Front View should be: SWRevealViewControllerSegueSetController and not the old SWRevealViewControllerSegue.
EDIT:
Also note that calling [self.revealController panGestureRecognizer]; is enough to enable the gesture; no need for an additional gesture.
EDIT:
Try initializing like this:
MenuViewController *menuVC = [self.storyboard instantiateViewControllerWithIdentifier:#"MenuViewController"];
UINavigationController *frontNavigationController = [self.storyboard instantiateViewControllerWithIdentifier:#"MainNavigationController"];
SWRevealViewController *revealViewController = [[SWRevealViewController alloc] initWithRearViewController:menuVC frontViewController:frontNavigationController];
EDIT:
Can you try adding an action to your Menu Button like this:
[menuButton addTarget:self.revealViewController action:#selector(revealToggle:)
forControlEvents:UIControlEventTouchUpInside];
Related
I want to add SWRevealViewController before my V1 and V2 controller. I don't know how to initiate the reveal-controlle.I added screen shots of my storyboard so its easy to understands all.
first extend your vc3 in any class.than apply storyboard identifier name in vc3.
write code in vc2 button click action method
vc3 *secondViewController =
[self.storyboard instantiateViewControllerWithIdentifier:#"storyboardidentifier name"];
[self presentViewController:second animated:YES completion:NULL];
Follow this link
http://www.appcoda.com/ios-programming-sidebar-navigation-menu/
Do as it says. In the view controller where you want your slide out menu use this
[menuBtn addTarget:self.revealViewController action:#selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside];
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
Make reveal view controller your initial view controller.
Note: Problem solved.
Here comes the story. I am using RevealViewController in my project. I am also hiding the navigationBars:
[self.navigationController setNavigationBarHidden];
My project can be seen in the picture below and the "menuButton" is implemented in the tabBarViewController.
Since the navigationBar is hidden due to my interface looks, all tabViews (HomeViewController) will not show the menuButton and the navigationBar as supposed to. I am not using panGestureRecognizer to trigger the menu aswell.
This means I have a problem to trigger the menu via a normal button in HomeViewController. The menuButton-event is placed in tabBarViewController.m:
_menuButton.target = self.revealViewController;
_menuButton.action = #selector(revealToggle:);
So I tried to call a method from HomeViewController to fire the button in tabBarViewController like this:
HomeViewController.m
- (IBAction) onMenuClicked: (id)sender{
tabBar = [[tabBarViewController alloc] init];
[tabBar setupMenu]:
}
tabBarViewController.m
-(void) setupMenu{
[_realMenuButton sendActionForControlEvents:UIControlEventTouchUpInside];
[_realMenuButton addTarget:self.revealViewController action:#selector(revealToggle:) UIControlEventTouchUpInside];
}
In this example I tried to make the realMenuButton and normal UIButton. Ive also tried as a UIBarButtonItem just to trigger the #selector(revealToggle:) But nothing happens in the app when I try to trigger the button from HomeViewController.
Not sure how I shall make this work. Any other Ideas or tricks? Please be specific if so! Regards
Yes, it will still work.
SWRevealViewController is just a subclass of a UIViewController, so you can use it at any point in the app:
By calling presentViewController:animated at some point.
By using it in a navigation stack etc.
Note that you can add gestures from SWRevealViewController to its content view controllers, which will alter the behaviour of used in a navigation view controller, but that's to be expected, and you still have full control over its behaviour.
Edit
The UI structure of your app is still not clear to me - it looks like you're trying to call revealToggle on an instance of SWRevealViewController when the VC in view is infact HomeViewController? How would this work, when SWVC is not even in view?
My best guess is that your UI structure should be as follows:
TabBarController --->(root)UINavigationController --->(root)SWRevealViewController.
Then, on your SWRevealViewController, set HomeViewController as the front view controller, and the TableViewController as the right or left view controller.
Do you mean like this?
it is possible. you can set the menu button in your tabBarController.m, like this :
UIBarButtonItem *menu = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"menu.png"] style:UIBarButtonItemStylePlain target:revealController action:#selector(revealToggle:)];
self.navigationItem.leftBarButtonItem = menu;
self.delegate = self;
For me, my initial view controller is the login screen (obviously I don't need reveal any VC here...). then when user tap the login button,
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:yourRootVC];
LeftMenuViewController *leftMenuVC = [[LeftMenuViewController alloc]init];
SWRevealViewController *revealController = [[SWRevealViewController alloc]initWithRearViewController:leftMenuVC frontViewController:nav];
revealController.delegate = self;
[self presentViewController:revealController animated:YES completion:nil];
I've tried it and it should work as normal. Even it isn't initial view controller
My iOS application is based on John-Lluch's SWRevealViewController to get sidebar navigation. I have ran into a navigation problem that I don't know how to solve.
I want one of the menu items to lead to a page that doesn't contain a sidebar but a back button instead. (The other menu items leads to pages where the sidebar can be opened).
To get a back button on a view I need to use a Show Detail Segue, but I also need a navigation controller "somewhere" for the back button to show up. (I don't mean that I need a navigation controller AFTER the segue - I have that already - but I need it somewhere before).
Have someone used SWRevealViewController in this way or know how to achieve this? "Where" should I place a navigation controller?
Thanks!
The only working solution I came up with was to use a Category on UIView, that could do my Detail Segues.
#interface UIViewController (SidebarView)
(void)setupSidebarWithGestureRecognizer:(BOOL)useGestureRecognizer;
(void)openSettingsPage;
(void)openAboutPage;
#end
and the .m-file's code for openAboutPage:
/* This method is called by the sidebar. If the sidebar opens the settings page from itself, the back button
* doesn't know where it should point. This method opens the about menu when the sidebar tells it to, and the back button
* is pointing to the home page. */
- (void)openAboutPage {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *about = [storyboard instantiateViewControllerWithIdentifier:#"About"];
[self.revealViewController rightRevealToggleAnimated:YES];
[self.navigationController pushViewController:about animated:NO];
self.navigationController.navigationItem.title = #"About";
}
and the setupSideBarWithGestureRecognizer... method
- (void)setupSidebarWithGestureRecognizer:(BOOL)useGestureRecognizer {
SWRevealViewController *revealViewController = self.revealViewController;
if (revealViewController) {
UIBarButtonItem *sidebarButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"reveal"] landscapeImagePhone:[UIImage imageNamed:#"reveal"] style:UIBarButtonItemStylePlain target:self.revealViewController action:#selector(rightRevealToggle:)];
self.navigationItem.rightBarButtonItem = sidebarButton;
if(useGestureRecognizer) {
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
}
}
Then for each page I want to show a sidebar, I just call [self setupSidebar:YES]; in the viewWillAppear method of that view controller.
I am trying to implement the JASidePanels in my project using storyboard. You can see my storyboard over here.
The problem is that I don't see the button in the navigationbar to reveal the leftpanel. In my RootViewController I've this in code.
-(void) awakeFromNib
{
[self setLeftPanel:[self.storyboard instantiateViewControllerWithIdentifier:#"leftViewController"]];
[self setCenterPanel:[self.storyboard instantiateViewControllerWithIdentifier:#"centerViewController"]];
[self setRightPanel:[self.storyboard instantiateViewControllerWithIdentifier:#"rightViewController"]];
self.shouldResizeLeftPanel = YES;
self.shouldResizeRightPanel = YES;
[self setRightFixedWidth:300.0f];
[self setLeftFixedWidth:300.0f];
}
I've followed the steps that they say on the github page.
Also when I try to embed the RootviewController inside a navigationController. It is showing the navigationBar but not the barbutton item.
Any help on this ?
Embed your center UIViewController in storyBoard into UINavigationController, for example:
Select UIViewController on StoryBoard
Select Xcode menu item Editor - Embed In - Navigation Controller
Select new UINavigationController's Identity Inspector (Alt-Command-3)
Give unique name to StoryBoard ID e.g. myCenterController
Use that name to create center panel
[self setCenterPanel:[self.storyboard instantiateViewControllerWithIdentifier:#"myCenterController"]];
So you don't actually set viewController as centerPanel, but a navigation controller containing your viewController.
Well, I'm using swift 2.2 and I couldn't either see the navigation button.
I'm using storyboards; so I created:
MainViewController -> this is going to be the main container
LeftMenuViewController -> this is the left menu
ProductsViewController -> this is going to be inside MainViewController
So in MainViewController, I set up my VC as follows:
self.leftPanel = self.storyboard?.instantiateViewControllerWithIdentifier("LeftMenuViewController") //for left menu and
self.centerPanel = UINavigationController.init(rootViewController: (self.storyboard?.instantiateViewControllerWithIdentifier("ProductsViewController"))!)
Adding UINavigationController.init will solve the problem, and you will see the navigation button in the center panel.
The above picture shows the schema of my app .. I created a custom view to show the content in UIViewController3 in 1 and 2.
I want to jump directly to VC4 when custom view is touched in VC1 and 2 ..
the custom view was a UIView, the I changed it to UIControl in Interface Builder, to receive touch event ..
I used the following code in custom view class touchevent method
- (IBAction)customViewTouched:(id)sender {
VC4 *nextController = [[VC4 alloc] initWithNibName:#"VC4" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:nextController];
[self presentViewController:navigationController animated:YES completion:nil];
navigationController.navigationBar.tintColor = [UIColor blackColor];
navigationController.navigationBar.topItem.title = #"My Title";
navigationController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(cancel)];
navigationController.navigationItem.hidesBackButton = FALSE;
// navigationController.navigationBar.backItem.title = #"back";
}
when custom view was touched in VC2(its getting called correctly) - VC4 pops , but only within the custom view..
Also I cant get a back button on the navigation bar. ( as suggested in other stackoverflow answers I also tried setting the custom view's title in ViewDidLoad)
3.I create a dummy UIButton in VC1 of customView's size and place the customView in it .. so that I can handle touch event on VC1 itself .. will this create any performance issues ?
[myCustomViewButton addTarget:self action:#selector(myEventHandler) forControlEvents: UIControlEventTouchUpInside];
when I use the above code, its not throwing any error, but the method myEventHandler never gets called .. in addTarget instead of 'self' when I use 'UIViewController' class name, its throwing an error..
I dont know how to proceed on this .. Any help is appreciated :)
I assume the unmentioned VC3 manages your custom view:
change [self presentVC] to [self.parentVC presentVC]
the VC3 you are presenting VC4 from is embedded as a child in VC1 and VC2