I have a table view and i put a ToolBar button so when button is clicked open a Map View.
When I click the button my application crash, so I tried this:
MapViewController *mvc = [[MapViewController alloc]initWithNibName:#"MapViewController" bundle:nil];
// NSArray *categories = nil;
switch ([indexPath row]){
case 0:
[self.navigationController pushViewController:svc animated:YES];
....
And when I tap a corresponding cell it open new view and my mapView is working like a charm
But when I put same in the Button action method my application crash.
Any ideas?
My guess is that you pass the wrong selector when you connect the button to the action.
If you have created the button programattically.
Don't forget to add it to the view.
The selector should look something like this: `[button addTarget:self action:#selector(pressButton1:) forControlEvents:UIControlEventTouchUpInside];
Note the : in pressButton1:
Related
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
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];
I have a tabbed application with one of the tabs being a map view. The user places a pin in a location and in the annotation callout there is a disclosure button. I want this button to push to a detail view with more specific details about the annotation. I have searched for related questions but none of them seem to have the same problem with it as I do. When the disclosure button is clicked, the application crashes with the exception: 'NSInvalidArgumentException', reason: '-[MapView tableView]: unrecognized selector sent to instance 0x8434360'
This is where I attempt to push the detail view controller. The log statement returns a navigation controller so it is not an issue of sending a message to nil.
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
DetailViewController *dvc = [[DetailViewController alloc] init];
NSLog(#"%#", [self navigationController]);
[[SpotsStore defaultStore] setSelectedSpot:[view annotation]];
[[self navigationController] pushViewController:dvc animated:YES];
}
I instantiated the navigation controller in the app delegate:
UINavigationController *mapnc = [[UINavigationController alloc] initWithRootViewController:mv];
[mapnc setNavigationBarHidden:NO];
[[mapnc tabBarItem] setTitle:#"Map"];
[[mapnc tabBarItem] setImage:[UIImage imageNamed:#"mapicon.png"]];
[tbc setViewControllers:[NSArray arrayWithObjects:nc,mapnc, nil]];
// nc is a different navigation controller I instantiated earlier.
[[self window] setRootViewController:tbc];
I would really like any help with this, or just send me in the right direction. I could not find anything about the navigation controller sending the method tableView. Or why it doesn't work in this case.
I would stongly recommend using storyboards. Create a tabbarcontroller. Create a navigationcontroller with 2 viewcontrollers: the first is the map iewcontroller, the second is the detailviewcontroller. Ste this navigationcontroller to be one of the tabbarcontrollers viewcontrollers.
In your calloutaccessorytapped method call performSegue with the identifier that you defined in the storyboatd.
I found the problem. It was a piece of code in my detail view viewWillAppear method in which i reloaded the tableView. Thanks for your help though!
I have a UITabBarController bassed app. I'm instantiating it from the app delegate and adding a custom button in the tab bar controller. when that button is clicked, I want to present another view modally, but I cant seem to figure out how to do it. to add the button I'm basically doing this
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[self.tabBarController.view addSubview:button];
[button addTarget:self action:#selector(showModalViewController:) forControlEvents:UIControlEventTouchUpInside];
and also in the app delegate I have a method
- (void) showModalViewController {
DummyViewController *addController = [[DummyViewController alloc]
initWithNibName:#"DummyViewController" bundle:nil];
//addController.delegate = self;
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0];
// Create the navigation controller and present it modally.
[self.tabBarController.selectedViewController presentModalViewController:addController animated:YES];
// The navigation controller is now owned by the current view controller
}
I keep getting unrecognized seletor
Your selector looks for a method named showModalViewController: but your actual method is named showModalViewController. Change one or the other.
Either change the selector to #selector(showModalViewController) to match the existing method, or change the method to:
- (void)showModalViewController:(UIButton *)button {
Don't change both.
My ipad project is master-detail view based. There is a button on detail view's toolbar, when user tap on the button, it popup a popover view to show four buttons (as menu). Three of buttons' actions are like the following (the three buttons show three different model form sheets):
- (void) showOnlineSgf
{
NSLog(#"showOnlineSgf");
TGOOnlineSgfViewController *dlg =
[[TGOOnlineSgfViewController alloc] initWithNibName:#"TGOOnlineSgfViewController"
bundle:nil];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:dlg];
[nav setModalPresentationStyle:UIModalPresentationFormSheet];
[self presentViewController:nav animated:YES completion:nil];
dlg = nil;
nav = nil;
}
The other button's action is to show a MFMailComposeViewController. Code is like the following:
- (void) emailCurrentGame
{
NSLog(#"email current game");
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[self presentModalViewController:picker animated:YES];
picker = nil;
}
The weird behavior is that when I tap the button what should execute showOnlineSgf(), but emailCurrentGame() is actually executed. When I set a breakpoint in showOnlineSgf(), it's hit, and step by step, each statement in showOnlineSgf() is executed. But the result on screen is a MFMainComposeViewController shows up.
I know this question is hard to answer. Any idea is appreciated.
Check your outlet connection of your UIButton that triggers showOnlineSgf. Most likely you copy pasted your UIButton in Interface Builder, which causes it to copy its assigned action as well. Then you've connected your other action, resulting in your UIButton having two actions.
To resolve the problem, simply disconnect your UIButton that triggers showOnlineSgf from the emailCurrentGame action.
Sounds like you copy pasted in the interface builder an already connected button. Check if the button has more than one action assigned.