I have a Master-Detail application. Both master and detail are UITableViewControllers. In detail scene I created a button and call to it action
- (IBAction)completeTaskButtonPressed:(id)sender {
[[self delegate] removeCompletedTask:self.indexFromRow controller:self];
}
In Master VC implementation I have method
- (void) removeCompletedTask:(NSInteger)index controller:(DetailViewController *) controller {
[self.dataController.masterTasksList removeObjectAtIndex:index];
[self.tableView reloadData];
[self dismissViewControllerAnimated:YES completion:NULL];
}
These method must delete selected row and go back to the Master View. The problem is that it removes the row but DONT dismiss detail view. Any help will be usefull.
Sounds like your master-detail setup involves a navigation controller. If you want to dismiss the detail view in the same manner as would tapping the Back button, use [self.navigationController popViewControllerAnimated:YES].
try
[self dismissModalViewControllerAnimated:YES];
or you could try:
[self.navigationController popViewControllerAnimated:YES].
You are popping the view controller which is the opposite of pushViewController:
Related
EDIT: Added code that contains the dismissal.
NEW DATA
The problem remains the same as the problem listed under old data, except the dismissal line has changed.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Yes"])
{
NSLog(#"Calling Dismissal...");
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
}
The function is being called because "Calling Dismissal..." is displayed in the log.
Current Hierarchy: UITabBarController - NavigationController/NavigationController - View1/View2
OLD DATA
In case the question was confusing, I am trying to dismiss a UITabBarController than I presented modally. The UITabBarController does use NavigationControllers to setup the two views inside. However, no matter how many parentViewController s I put in
(i.e.):
[self.parentViewController.parentViewController.etc... dismissViewControllerAnimated:YES completion:nil];
The UITableBarController will not dismiss. I have a button being placed in the NavigationController of both views that is calling the line of code above. Any hints on how to dismiss the UITableViewController?
The presenting view controller, which is not the same concept as the parent view controller, needs to dismiss it. This code:
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
will typically do the trick.
However, depending on what this controller's function is, I usually prefer to have my presented controllers send a delegate message or NSNotification to the parent, so the parent can extract whatever data it needs before dismissal.
I'm performing a segue with a navigation bar over a view that has the navigation bar hidden, when the segue starts my current view seems to get pushed down by the navigation bar that is not hidden in my segue… which looks bad…
If I remove the setNavigationBarHidden:animated method I don't see a navigation bar after performing the segue, and the issue doesn't manifest anymore.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.navigationController setNavigationBarHidden:NO animated:YES];
if (indexPath.row == 0) {
[self performSegueWithIdentifier:#"mailSignUp" sender:nil];
} else if (indexPath.row == 1) {
[self performSegueWithIdentifier:#"logIn" sender:nil];
}
}
If you want to hide your navigation bar you have to do it in the root controller, the first controller in your app.
My guess is that you have had setup a modal segue in interface builder from a certain button to the following view. By doing so you have the following view sliding in from down to top.
I'm also guessing you are using the lastest xcode version [4.5.2] and running it on ios6.
Try deleting your segue from interface builder. Also, instead of your:
[self performSegueWithIdentifier:#"mailSignUp" sender:nil];
use:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
YourSecondController *secondController = (YourSecondController *)[storyBoard instantiateViewControllerWithIdentifier:#"YourSecondController"];
[self.navigationController pushViewController:yourSecondController animated:YES];
[substitue YourSecondController with mailSignUp or whatever controller you want to perform segue to]
Also, if you want to hide your navigation bar you have to add this line of code in your (void)viewdidload method in your root controller.
If you run your segue programmatically like this, you should achieve your second view slide from right to left. Let me know if this helped or provide more info if it is not sufficient or exact.
I'm trying to make a modal view controller in my app delegate (I created a function called showLoginView). But whenever I try to call it I get a warning in XCode:
Warning: Attempt to present <PSLoginViewController: 0x1fda2b40> on <PSViewController: 0x1fda0720> whose view is not in the window hierarchy!
Here's the method code:
- (void)showLoginView
{
PSLoginViewController *loginViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:#"PSLoginViewController"];
[self.window.rootViewController presentViewController:loginViewController animated:NO completion:nil];
}
How can I add the view to the window hierarchy? Or maybe I'm doing something very wrong?
You can't display a modal view controller from the appDelegate. You need to display a modal ViewController from whichever viewController is currently displaying full-screen. In other words, you need to put that code into your root view controller, or whichever one you want to display the modal vc from...
Also, you'll want to use the method "presentModalViewController" to present the modal. You can set properties on the modal vc such as:
vC.modalPresentationStyle = UIModalPresentationFormSheet;
vC.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:vC animated:YES];
You can actually present a modal view Controller from the AppDelegate as long as you detect the current visible viewController and take care of the case where you current controller is a navigationController.
Here is what I do:
UIViewController *activeController = [UIApplication sharedApplication].keyWindow.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]]) {
activeController = [(UINavigationController*) activeController visibleViewController];
}
[activeController presentModalViewController:loginViewController animated:YES];
UIViewController *activeController = [UIApplication sharedApplication].keyWindow.rootViewController;
if ([activeController isKindOfClass:[UINavigationController class]])
{
activeController = [(UINavigationController*) activeController visibleViewController];
}
else if (activeController.modalViewController)
{
activeController = activeController.modalViewController;
}
[activeController presentModalViewController:vc animated:YES];
I ran into this problem on iOS 7 - the key to making any of the proposed solutions work was to call
[self.window makeKeyAndVisible];
in your AppDelegate.
After that call, presenting a modal view from the window's rootViewController worked.
Another reason for that warning can be that you want to present a view controller from an instance which is not the top most view controller.
So first you have to get the topmost UIViewController and using this instance to call presentViewController:
UIViewController *root = [UIApplication sharedApplication].keyWindow.rootViewController;
while (root.presentedViewController) {
root = root.presentedViewController;
}
You can NSLog(#"%#", self.window.rootViewController), and see what the rootViewController really is.
I came into this problem, when the rootViewController is a normal UIViewController.
Replace it with a UINavigationController, wish it will help.
Faced this issue while trying to present controller from the call of delegate of other controller . i.e : show search filter with delegate , once done back to my controller and receive data via the delegate then present controller , all I had to do is to dispatch the present code cause while in a delegate you're in another thread , that's why you're presenting on your view from main thread another controller from that other thread , so have to go back to main thread , just put the presenting code like this :
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:searchVC animated:true completion:nil];
});
Hope this helps !
I'm building an app that currently has 3 ViewControllers. One of them is used after a successful login so is not relevant in this question.
I'm using a mixture of Storyboards and building things programmatically when I find Storyboards do not give me the fine control that I need.
The first ViewController is built in my 'MainStoryboard'. It has a login form and an info button at the bottom. I link it up the my AppDelegate by doing the following inside didFinishLaunchingWithOptions:
ViewController *viewController = (ViewController *)self.window.rootViewController;
Because I wanted to force rendering of a UIWebView (another story) I create the second view programmatically. I do the following inside didFinishLaunchingWithOptions:
infoViewController = [[InfoViewController alloc] init];
[infoViewController view];
Inside both of my ViewControllers I setup a link to appDelegate as below:
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
I have an info button in my first ViewController that takes you to the infoViewController. It calls the following code when tapped:
appDelegate.infoViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:appDelegate.infoViewController animated:YES];
The above works just fine for me, flips over the screen and shows the InfoViewController.
On my InfoViewController I have a button that should take you back to the login page, I have tried all sorts to get this to work but it just crashes my app. Nothing seems to work. I have tried the following:
appDelegate.viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:appDelegate.viewController animated:YES];
and
[self.navigationController popToRootViewControllerAnimated:YES];
and
[self.navigationController popViewControllerAnimated:YES];
and
[self.navigationController popToViewController:appDelegate.viewController animated:YES];
I suspect the last 3 might be more to do with when you have a navigation view controller and you want to go back to the root? I'm not sure, but either way it does not work. I had this working using storyboards previously so I'm sure it ought to be easy! As mentioned I switched to making the infoViewController programmatically so that I could force the UIWebView to render before the view appeared.
Any help much appreciated.
You can do with:
[self dismissModalViewControllerAnimated:YES];
You should use this.
[self dismissModalViewControllerAnimated:YES];
You should use a main controller for switching between your other view controllers. Change the view of your root controller to one of your other view controllers (apply animations as usual if needed). Hold a pointer to your root controller in your other view controllers and call self.rootController.view = <desired_controller_instance>.view
I think the way you're presenting your InfoViewController is wrong. Do it the following way:
In your ViewController, create an action for the info button.:
- (IBAction)infoButtonTapped:(id)sender
{
InfoViewController *infoViewController = [[InfoViewController alloc] init];
infoViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:infoViewController animated:YES];
}
And in your InfoViewController, in the action of your button that should take you back write this:
- (void)takeBackToViewController
{
[self dismissModalViewControllerAnimated:YES];
}
Hope it works.
Also in presented controller you can use this
if(self.parentViewController)
[self.parentViewController dismissModalViewControllerAnimated:YES];
else
[self.presentingViewController dismissModalViewControllerAnimated:YES];
To dissmiss current controller.
this is a newbie question.i ve created a grouped tableview .on clicking the tableview cell it navigates to a new view.but i m unable to create a back button.I even added a navigation bar in the second view of the nib file.but its of no effect..could you guys help me out..below is the screenshot and code of the first view
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
if (indexPath.row==0) {
self.dvController1 = [[FirstView alloc] initWithNibName:#"FirstView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController1 animated:YES];
}
if (indexPath.row==1) {
self.dvController2 = [[Tab4 alloc] initWithNibName:#"Tab4" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController2 animated:YES];
}
}
In the presented controller add a button with an IBAction in it:
- (IBAction)back:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
And make sure that you have a navigationController indeed (meaning that your application needs to be navigation oriented, meaning that you need to instantiate the navigationController property in the application delegate)
In your second view .put this code in viewDidLoad method
self.navigationItem.leftBarButtonItem.title = #"Back";
just hide the bar in the viewWillAppear method & unhide the bar in viewWillDisAppear methods of the tableViewController class. By using
self.navigationController.navigationBarHidden = YES/NO;