I am new to iOS Programming and now i have a problem.
There is a login screen that use [self presentViewController:loginview animated:YES completion:nil]; to show it out in MasterViewController.
And now i want to call a method (reload data) after [self dismissViewControllerAnimated:YES completion:nil]
this is my code:
[self dismissViewControllerAnimated:YES completion:^ {
[self getPostData]; // Reload Data
[self.tableView reloadData]; // Reload Data
}];
but it is not working.
(the reload method is in the MasterViewController)
Anyone can help me?
You can use NSNotificationCenter for your problem.
Define a NSNotification in your MasterViewController viewDidLoad like below
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(closeModal:) name:#"CloseModal" object:nil];
And then define the method as below
-(void)closeModal:(NSNotification *)notification{
UIViewController *controller=(UIViewController *)notification.object;
[controller dismissViewControllerAnimated:YES completion:^ {
[self getPostData]; // Reload Data
[self.tableView reloadData]; // Reload Data
}];
}
And at last from your other controller from where you are actually trying to dismiss your controller use code below
[[NSNotificationCenter defaultCenter] postNotificationName:#"CloseModal" object:self];
what you should do is basically call method on presenting view controller as below
[(MasterViewController*)self.presentingViewController reloadData];
You can call the presentingViewController's methods which updates the Presenting view.
for example: I have a modal view which can be launched from multiple Views. And all the presenting views have the view reloading code within view will appear.
Add the below code before dissmissing the modal view.
[self.presentingViewController viewWillAppear:YES];
[self dismissViewControllerAnimated:YES completion:Nil];
Related
I created a library, and if the main app call my library its showing it, and download some data from server. But if the server has some error I would like to kill the library view, but it's not working
I have a delegate in the host app:
-(void)libraryResult:(NSString*)result{
NSLog(#"result: %#", result);
}
And I download data from server in the viewWillAppear method, and the download has a delegate method like this:
-(void)networkManagerError:(NSString *)error{
[hud hide:YES];
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
[self.delegate libraryResult:error];
}
I see in the log, that the app return to the main app, but the view don't change.
How to solve this? Whats wrong with my code?
Change this line
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
To
[self dismissViewControllerAnimated:YES completion:nil];
try these..
[self dismissViewControllerAnimated:YES completion:nil];
If you have VC1 which presents VC2, then inside VC2 at the corresponding event (say a Close button tap, or error from server etc.), you should call:
[self.presentingViewController dismissViewControllerAnimated:YES completion:^{
}]
If you set up things in such a way that VC1 is notified about those events that happen inside VC2, you can use:
[self dismissViewControllerAnimated:YES completion:nil];
However, the 1st method is more preferred, as it's a better design practice, and contributes to more loose coupling between VC1 and VC2.
Try to fire a notification from your "library result" method if error occurred and add an observer to your current controller view.
[[NSNotificationCenter defaultCenter] postNotificationName:Remove_CurrentView object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(remove) name:Remove_CurrentView object:nil];
-(void)remove{
[self dismissViewControllerAnimated:YES completion:nil];
}
I have a strange problem in my app. When I'm pressed backButton from UINavigationController I trying to handle it with -(void) viewWillDisappear:(BOOL)animated in a next way:
-(void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated] ;
[self dismissViewControllerAnimated:YES completion:^{
[self.navigationController popToRootViewControllerAnimated:YES];
}];
}
After it I want do some code in -(void)viewDidAppear:(BOOL)animated of my rootTableViewController. But it's seems like that method wasn't called, but my controller
is changed to root(visual at least ). Have you any idea what I do wrong & how to resolve it?
I have a view A, a view B and a view C. The idea is : I'm presenting view B on view A, view B has a delegate in view A that performs a segue : view C.
My problem is I have the message "Attempt to present view B on view A while a presentation is in progress!".
I can make it work adding a delay in the method of view A that performs the segue, but isn't there a better way to make it work ?
In view A, the delegate method :
- (void)addItemViewController:(NSString *)string text:(NSString *)textfield{
[self barcodeData:string type:1 :^(BOOL finished) {
if(finished){
[self performSegueWithIdentifier:#"viewC" sender:self];
}
}];
}
In view B
[self.delegate addItemViewController:saisieManuelleTextView.text text:nil];
[self dismissViewControllerAnimated:NO completion:nil];
Try invoking the delegate in the animation completion handler (some overlap in postings as redent84 also suggested this):
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate addItemViewController:saisieManuelleTextView.text text:nil];
}];
That way you're still getting the benefits of the delegate and avoid the possibility of simultaneous view controller animations.
Better yet, if view A presents view B, then make viewA responsible for dismissing viewB as well, instead of having viewB dismiss itself. That way viewB doesn't have to know how it was presented in the first place:
- (void)addItemViewController:(NSString *)string text:(NSString *)textfield{
[viewB dismissViewControllerAnimated:YES completion:^{
[self barcodeData:string type:1 :^(BOOL finished) {
if(finished){
[self performSegueWithIdentifier:#"viewC" sender:self];
}
}];
}];
}
The problem that you are seeing is related to the animation of the transitions. You are trying to animate the transition from view A to view C while there's already a transition active from view B back to view A.
Try using the completion block of the dismissViewControllerAnimated method:
[self dismissViewControllerAnimated:YES completion:^{
[self performSegueWithIdentifier:#"MySegue" sender:self];
}];
Or try disabling the animation of the transition from the view B to view A so it doesn't affect at all:
// For navigation controllers
[self.navigationController popViewControllerAnimated:NO];
// For modal controllers
[self dismissViewControllerAnimated:NO completion:nil];
EDIT:
You are presenting the new controller before dismissing the previous one, change the following lines:
[self.delegate addItemViewController:saisieManuelleTextView.text text:nil];
[self dismissViewControllerAnimated:NO completion:nil];
to this:
[self dismissViewControllerAnimated:NO completion:nil];
[self.delegate addItemViewController:saisieManuelleTextView.text text:nil];
Alternatively, you can maintain the animation using the completion block as described above:
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate addItemViewController:saisieManuelleTextView.text text:nil];
}];
There are 3 view controllers View1,View2 and View3.
From view3 I have to navigate to view1.
I have tried the following code but it doesn't work.
//in View3.m
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
{
appDelegate.isComingFromCountries = YES;
[self dismissViewControllerAnimated:YES completion:nil];
}
//in View2.m
-(void)viewWillAppear:(BOOL)animated
{
if (appDelegate.isComingFromCountries == YES)
{
appDelegate.isComingFromCountries = NO;
[self dismissViewControllerAnimated:YES completion:nil];
}
}
But this code doesn't work. How do I handle this?
You can use use presentingViewController for dismissing it,
try this -
[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];
A -> B -> C
Running the above code in modal C will take you back to A.
You have to use delay method to perform animation so that main thread should start performing in B viewController
[self performSelector:#selector(methodForDissmiss) withObject:nil afterDelay:0.5];
then write dismiss code in selector method to work by your logic.
If you are returning to the root view controller from a series of modally presented view controllers then the following code will work in iOS6
[self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
I think, It may help you. According to your code( in comments area), You second view controller push from first view controller, then present third from second. So you have to set delegate as second in third. And do your code as below in third VC.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
{
appDelegate.isComingFromCountries = YES;
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate dismissModal];
};
}
In SecondVC.m
-(void)dismissModal
{
[self.navigationController popViewControllerAnimated:NO];
}
Also you can pop to view 1 from view 3 on like this:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
[self.navigationController dismissViewControllerAnimated:NO completion:nil];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
You can try this one :
if you are pushing one viewController to another and want to move back then use this one
[self.navigationController popViewControllerAnimated:YES];
if you are presenting viewController use modelly and want to move back then use this one
[picker dismissViewControllerAnimated:YES completion:nil];
also you can try this because first you need to dismiss third viewController then second one.
UIViewController *viewController = [self parentViewController];
[self dismissModalViewControllerAnimated:NO];
[viewController dismissModalViewControllerAnimated:YES];
I have a tab bar controller with a view inside a navigation controller. One of the buttons on this pops up a modal view. I set my starting view as the delegate for the modal, and call the following:
- (void)dischargeSaveComplete:(dischargeView *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
[self.navigationController popViewControllerAnimated:YES];
}
It correctly dismisses the modal view, but it doesn't call the back button. Do I need to do something else since it's inside a tab bar controller?
I tried set both to animation no as seen below, and it doesn't work either.
- (void)dischargeSaveComplete:(ehrxEncounterDischargeView *)controller
{
[self dismissViewControllerAnimated:NO completion:nil];
[self.navigationController popViewControllerAnimated:NO];
}
Found the solution based on one of the answers, because I was in a tab bar controller, I had to call the popviewcontroller from the first view as seen below:
- (void)dischargeSaveComplete:(ehrxEncounterDischargeView *)controller
{
[self dismissViewControllerAnimated:YES completion:^(void)
{
demoView *e = [self.parentViewController.tabBarController.viewControllers objectAtIndex:0];
[e.navigationController popViewControllerAnimated:YES];
}];
}
You want 2 animations to follow one another, which is not allowed as you did it. You either have to cancel one of the animation or place popViewController inside the completion block for your first animation.
[self dismissViewControllerAnimated:YES completion:^(void) {
[self.navigationController popViewControllerAnimated:YES];
}
];
u can try delay in performing second action
[self.navigationController performSelector:#selector(popViewControllerAnimated:) withObject:#"YES" afterDelay:1];
hope it works.. happy coding :)