I have two programmatically created buttons you can see in my viewDidLoad method. On the modal window I have a button that calls the cancelSearch method via a delegate. When I place a breakpoint on my cancelSearch method it is hit, so I know my delegate is set up correct, but even though it calls this line [self dismissViewControllerAnimated:YES completion:nil]; it's not actually closing the modal window.
The code below is all from my main controller view.
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *actionButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:#selector(showActionMenu:)];
actionButton.style = UIBarButtonItemStyleBordered;
UIBarButtonItem *searchButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(showSearchMenu:)];
searchButtonItem.style = UIBarButtonItemStyleBordered;
UIToolbar* toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 103.0f, 44.01f)];
NSArray* buttons = [NSArray arrayWithObjects:actionButton, searchButtonItem, nil];
[toolbar setItems:buttons animated:NO];
self.navigationItem.title = #"Census Management";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:toolbar];
[[RKClient sharedClient] get:#"censusmanagement" delegate:self];
}
- (IBAction)showActionMenu:(id)sender
{
[self performSegueWithIdentifier: #"CMActionSegue" sender: self];
}
- (IBAction)showSearchMenu:(id)sender
{
ehrxCMSearchView *search = [[self storyboard] instantiateViewControllerWithIdentifier:#"cmSearch"];
search.selectedOptions = self.selectedOptions;
search.delegate = self;
[self.navigationController pushViewController:search animated:YES];
}
- (void)cancelSearch:(ehrxCMSearchView *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
You would dismiss a modal view using something similar to:
[self dismissModalViewControllerAnimated:YES];
This will dismiss the modal view which was loaded using something similar to:
[self presentModalViewController:search animated:YES];
However looking at your code snippet, it appears the search view controller is being pushed onto the navigation stack using the following line:
[self.navigationController pushViewController:search animated:YES];
So I you probably need to pop the view from the navigation stack rather than trying to dismiss it as a modal view:
[self.navigationController popViewControllerAnimated:YES];
If your view controller is modally presented, you should use this:
[self.presentingViewController dismissModalViewControllerAnimated:YES];
The presentingViewController property is available in iOS 5 only. So, if you're targeting older versions of iOS, you have to use self.parentViewController instead (use the appropriate one for each iOS version, you have to handle this).
If you make this control in your parent/presenting view controller, then just call this:
[self dismissModalViewControllerAnimated:YES];
Related
I have some code that builds and displays a viewController inside a navigation controller. The first time through the handleDoubleTapRecognizer everything works as expected. However, EVERY time thereafter that handleDoubleTapRecognizer is triggered, the navigation controller and its content controller, built in the handleDoubleTapRecognizer never appear, and instead I get this delightful message in the console...
Warning: Attempt to present <UINavigationController: 0x7bbafa00> on <iRpImageViewerViewController: 0x80164580> whose view is not in the window hierarchy!
Also note that [self.view superview] returns nil, so something is totally destroying the connections from this view to its parent.
...
#implementation iRpImageViewerViewController
{
IGGridView *theMainImageGridviewControl;
iRpImageSet *thePropertyImageSet;
iRpImageFilmstripViewController *theFilmstripViewController;
iRpImageAndMedia *initialMediaItem; // The item to display when first loaded.
UIImageView *primaryImageMarker;
UINavigationController *imageEditorNavController;
iRpImageEditorViewController *imageEditorVC;
}
...
-(void)handleDoubleTapRecognizer:(UITapGestureRecognizer*)recognizer
{
NSLog(#"Double Tapped on ImageViewerViewController's main image, so opening editor");
IGCellPath *pathForCurrentCell = [self pathForCurrentCell];
iRpImageAndMedia *imageAndMediaItem = [thePropertyImageSet objectAtIndex:pathForCurrentCell.columnIndex];
imageEditorVC = [[iRpImageEditorViewController alloc] initWithImageAndMediaItem:imageAndMediaItem];
imageEditorVC.navigationItem.title = #"Photo Details Editor";
imageEditorVC.edgesForExtendedLayout = UIRectEdgeNone;
imageEditorNavController = [[UINavigationController alloc] initWithRootViewController:imageEditorVC];
imageEditorNavController.modalPresentationStyle = UIModalPresentationFormSheet;
imageEditorNavController.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(imageEditorDone)];
imageEditorNavController.topViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(imageEditorCancelled)];
imageEditorNavController.preferredContentSize = imageEditorVC.view.frame.size;
NSLog(#"%#'s parentViewController is %#",self, self.parentViewController);
[self presentViewController:imageEditorNavController animated:YES completion:^(void){ }];
}
-(void)imageEditorDone
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void)imageEditorCancelled
{
[self dismissViewControllerAnimated:YES completion:nil];
}
I want to go to a view controller when the button "Cancel" is pressed. I tried using this method but when I click 'Cancel", it just displays a black screen. I am a beginner at IOS.
-(void) cancelButtonPressed {
homeView = (HomeViewController *)[[UIViewController alloc]init];
[self presentViewController:homeView animated:YES completion:nil];
}
EDITED FOR COMMENTS:
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(cancelButtonPressed)];
self.navigationItem.leftBarButtonItem = cancelButton;
Try doing this:
HomeViewController *homeView = [[HomeViewController alloc]init];
[self presentViewController:homeView animated:YES completion:nil];
Also note that black is the default colour of the window. If you don't have any view controller named HomeViewController, and you present it, by default it will be visible as black colour to the user.
To Avoid this, you need to set the View for the newly presented view controller, which you can access by homeView.view
If you are using storyboard, then use storyboard ID:
HomeViewController *homeView = [self.storyboard instantiateViewControllerWithIdentifier:#"HomeViewController"];
[self presentViewController:homeView animated:YES completion:nil];
I am looking today for some insight into the issue that I am facing with my app.
I have a tab bar based application (3 tabs). In tab #2, here's the sequence of events.
"Add" button clicked in the rootView of tab #2.
Table View with navBar presented modally (PresentViewController).
Table Row touched.
New UINavigationController presented with it's rootViewController showing a few images
One of the images is selected
Present new view modally with navBar (presentViewController) with Image and details.
7 Upon clicking the image, I want to go back to the root view of tab # 2. (and I am using delegates for this)
My problem is that
=> Unless I dismiss each and every modal view, I am unable to go to the tab# 2.
=> If I am using delegate and setting the selectedTabIndex = 1 in the delegate the rootViewController of tab #2 should get displayed.
=> But In actuality that doesn't happen till i dismiss both modal view controllers. Why is that?
I read in the apple documentation that if you dismiss a modal view controller then all the subsequent view controllers would be dismissed as well. This however does not seem to be the case. I can get back to the root view controller of tab#2 only after I dismiss each and every modal view.
//AppDelegate :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.tabBarController = [[UITabBarController alloc] init];
self.secondViewController = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
self.navControllerTwo = [[UINavigationController alloc] initWithRootViewController:self.secondViewController];
//navControllerOne and viewControllerOne are also init'd here
NSArray *viewControllers = [NSArray arrayWithObjects:self.navControllerOne, self.navControllerTwo, self.viewControllerOne, nil];
[self.tabBarController setViewControllers:viewControllers];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
// Then => 1. "Add" button clicked in the rootView of tab #2.
- (void)addItemButtonClicked:(id)sender
{
UIBarButtonItem *btn = nil;
AddItemViewcontroller *addItemController = [[AddItemViewcontroller alloc] initWithNibName:nil bundle:nil];
addItemController.delegate = self;
UINavigationController *addItemNavController = [[UINavigationController alloc] initWithRootViewController:addItemController];
//leftBaButton
btn = [[UIBarButtonItem alloc] initWithTitle:#"Cancel"
style:UIBarButtonItemStylePlain
target:self
action:#selector(addItemCancelButtonPressed:)];
addItemNavController.navigationBar.topItem.leftBarButtonItem = btn;
[self presentViewController:addItemNavController animated:YES completion:nil]; // First Modal View presented
}
//Then: => 2. Table View with navBar presented modally (PresentViewController).
// 3. Table Row touched.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
IGViewController *gvc = [[IGViewController alloc] initWithItemType:itemType]; // pre-determined item type
[self. navigationController pushViewController:gvc animated:YES];
}
//Then: 4. New UINavigationController presented with it's rootViewController showing a few images
// 5. One of the images is selected
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
{
UIBarButtonItem *btn;
UINavigationItem *navItem = [[UINavigationItem alloc] init];
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 44)];
SIViewController *siViewController = [[SIViewController alloc] initWithNibName:nil bundle:nil];
siViewController.delegate = self.appDelegate.secondViewController; // Init'd in the app delegate
btn = [[UIBarButtonItem alloc] initWithTitle:#"Add item" style:UIBarButtonItemStyleDone
target:selectedItemViewController
action:#selector(selectedItemViewAddItemButtonPressed)];
[navItem setLeftBarButtonItem:btn];
navBar.items = [NSArray arrayWithObject:navItem];
[navBar setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[selectedItemViewController.view addSubview:navBar];
[self presentViewController:selectedItemViewController animated:YES completion:nil]; //second modal view presentd here
}
//Then: 6. Present new view modally with navBar (presentViewController) with Image and details.
// 7 Upon clicking the image, I want to go back to the root view of tab # 2. (and I am using delegates for this)
-(void)siViewAddItemButtonPressed
{
[self.delegate selectedItemViewAddItemButtonPressedForItem:self.selectedItem];
}
//And: Here's what the method in the siViewControllers delegate looks like:
//In this routine setSelectedIndex = 2 does not work until i dismiss both modally presented views
- (void)siViewAddItemButtonPressedForItem:(Item *)item
{
[self.presentedViewController dismissViewControllerAnimated:NO completion:nil]; // Dismiss modal
[(UINavigationController*)(self.presentedViewController) popToRootViewControllerAnimated:NO];
[self.presentedViewController dismissViewControllerAnimated:NO completion:nil]; //Dismiss modal
}
I have below code that will call a modal view. I works fine when presenting the view controller but when i dismiss it, it crashes
_surveySummaryTableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
[_surveySummaryTableViewController setTableView:_surveySummaryTableView];
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(closeModalView:)];
[[_surveySummaryTableViewController navigationItem] setRightBarButtonItem:doneItem];
[[_surveySummaryTableViewController navigationItem] setTitle:#"Response Summary"];
navController = [[UINavigationController alloc]initWithRootViewController:_surveySummaryTableViewController];
[navController setModalPresentationStyle:UIModalPresentationFormSheet];
[navController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
....
[self presentViewController:navController animated:YES completion:nil];
Clicking on the DONE button on the modal view will call the closeModalView: method below:
- (void)closeModalView:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
The weird part is, when I comment out the line below, the dismiss works fine. But of cause, the view will be empty without any TableView. What could I have missed? I tried other suggestions posted by others in SO but no luck. Thanks in advance.
_surveySummaryTableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
//[_surveySummaryTableViewController setTableView:_surveySummaryTableView]; //This line commented out
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(closeModalView:)];
[[_surveySummaryTableViewController navigationItem] setRightBarButtonItem:doneItem];
[[_surveySummaryTableViewController navigationItem] setTitle:#"Response Summary"];
===Additional info===
Considering it works when the line above being commented, the table actually populates a custom UITableViewCell. Could that be a problem?
I changed the property type from retain to strong for surveySummaryTableView
#property (strong, nonatomic) IBOutlet UITableView *surveySummaryTableView;
And be sure to make the child views to be of type weak or unsafe_unretained
Thanks #JeslyVarghese & everyone!
Since you are pushing navController, you must dismiss that. Try:
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
OR
[self.parentViewController.navigationController dismissViewControllerAnimated:YES completion:nil];
I have created a UINavigationBarButton where i have placed a button called "update".When update button is clicked it is navigating to SecondViewController.But the problem is in the SecondViewController TabBar is not showing.What I'm trying to do is when i tap the back button in the SecondViewController it should get back to RootViewController.Here is the code
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title=#"GooGle";
[self.navigationItem setLeftItemsSupplementBackButton:YES];
[self.navigationController setToolbarHidden:NO];
UIBarButtonItem *nextView = [[UIBarButtonItem alloc] initWithTitle:#"update" style:UIBarButtonSystemItemPlay target:self action:#selector(updateAddress)];
self.navigationItem.rightBarButtonItem = nextView;
[nextView release];
}
-(void)updateAddress
{
SecondViewController *updateView=[[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController presentViewController:updateView animated:YES completion:Nil];
[self.navigationItem setLeftItemsSupplementBackButton:YES];
}
When you tap the back button in SecondViewController use
[self dismissViewControllerAnimated:YES completion:nil];
Since you are not using
[self.navigationController pushViewController:youViewController animated:YES];
the navigationbar won't be visible, if you do so you will have your navigationbar and a back button by its own and while pressing the back button it will itself move to the previous view
share your results