Attempt to dismiss from view controller - ios

I have an two class, in first class
- (IBAction)Login:(id)sender {
SampleViewController2 *sampleView = [[[SampleViewController2 alloc] init];
[self presentModalViewController:sampleView animated:YES];
}
in second class..
- (IBAction)Logout:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
it says warning Attempt to dismiss from view controller.. what is the problem here..

Add this:
if (![[self modalViewController] isBeingDismissed])
[self dismissModalViewControllerAnimated:YES];
Do a simple google search, the problem that you stated is common...

You might check it before dismissing if your current view's modal view is being dismissed or not
if (![[self modalViewController] isBeingDismissed]){
[self dismissModalViewControllerAnimated:YES];
}

Related

Issues presenting UIActivityViewController

I want to give a share screen throughout my app. I am using UIActivityViewController for that purpose. The problem is, as per your location in the app, the current root view controller can be of kind UINavigationController(Case1) or UIViewController(Case2).
I can present UIActivityViewController using
[viewController presentViewController:viewController animated:YES completion:nil];
But I have to get currently visible UIViewController of UINavigationController in (Case1), and root view controller itself in (Case2).
But how to detect which kind of root view controller is present & code accordingly?
Thanks.
Try:
UIViewController *root = [[[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0] nextResponder];
and then:
if ([root isKindOfClass:[UINavigationController class]]) {
// Navigation Controller
} else {
// The other one
}
that should tell you which one is presented.
Use the above method to detect for a UINavigationControler;
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//If this will be called it is a navigation controller
}
use performselector to start and stop rorating activity indicater
Here AI is activity indicater variable name
[self performSelector:#selector(animateAI) withObject:self afterDelay:0.1];
[self performSelector:#selector(stopAI) withObject:self afterDelay:0.9];
-(void)animateAI
{
[AI startAnimating];
}
-(void)stopAI
{
[AI stopAnimating];
}

How to move back to the viewcontroller?

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];

remove ViewController from parent screen stays black

I'm having trouble with removing a modal view.
I want to show (after pressing a button) a my own SendMailViewController which it self shows a MFMailComposeViewController. Then and after pressing cancel of send, in my own SendMailView controller in didFinishWithResult i do a [self dismissModalViewControllerAnimated:YES] and that works. The MFMailComposeView goes away.
But then the screen stays black....it think i also have to remove my SendMailViewController from it's parent. That's where i pushed the button...even after [self removeFromParentViewController] it still stays black...
Where do i go wrong?
And yes i would like the extra viewcontroller (SendMailViewController) because that controller will become the delegate of MFMailComposeViewController. Otherwise my caller (controller with the button) get's to much responsibility. Or do i also go wrong here?
Thanks,
/jr00n
- (IBAction)tapExportButton:(id)sender
{
SendMailViewController *sendMailController = [[SendMailViewController alloc]init];
[self presentViewController:sendMailController animated:YES completion:^() {[sendMailController openMailDialog];}];
[sendMailController release];
}
SendMailViewController:
- (void)openMailDialog
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
...
[self presentModalViewController:mailer animated:YES];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
....
// Remove the mail view
// first i did this:
// [self dismissModalViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:^{[self removeFromParentViewController];}];
}
The problem is with the [self dismissViewControllerAnimated:YES completion:^{[self removeFromParentViewController];}]; in your didFinishWithResult method.
Remove that line and add the following line,
[controller dismissViewControllerAnimated:YES completion:^{[self dismissViewControllerAnimated:YES completion:nil]}];
That make sure we dismiss the controller after dismissing the MailController

Instance method '-presentViewController:animated' not found

I'm fairly new to this, so bear with me. I have 2 errors left to fix in my code. In both cases my instance methods are not found:
-(IBAction)goFlipSide {
NSLog(#"goFlipSide has been called:");
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideViewController" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:controller animated:YES];
[controller release];
}
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller {
[self dismissViewControllerAnimated:YES];
//This method gets fired when the user clicks done on the modal FlipsideViewController. This is different
//than the viewWillAppear.
self.navigationController.navigationBarHidden = TRUE;
/*
if (self.goViewSuccess == TRUE) {
//if the goViewSuccess boolean is set to YES - then we can load the load the goViewController
NSLog(#"goViewSuccess is YES");
[self loadGoViewController];
}
*/
}
Both instance methods not found are: presentViewController: and dismissViewControllerAnimated:.
What class is self? Those methods are only found on UIViewController. The full selectors are:
presentViewController:animated:completion:
dismissViewControllerAnimated:completion:
Try adding the completion block argument.
The code is supposed to be this
[self dismissViewControllerAnimated:YES completion:nil];
or if you want something when its done,
[self dismissViewControllerAnimated:YES completion:^{
//do stuff
}];
And for the other one
[self presentViewController:controller animated:YES completion:nil];

Presenting view not appearing properly after MFMessageComposeViewController is presented and then dismissed

I have a View Controller which displays a table view. The VC calls another VC to display the send SMS view to the user, the code for this SMS VC is:
- (void) sendSMSWithBody: (NSString*) body andRecipients: (NSArray*) recipients
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if ([MFMessageComposeViewController canSendText])
{
controller.messageComposeDelegate = self;
controller.body = body;
controller.recipients = recipients;
[[UIApplication sharedApplication].delegate.window.rootViewController addChildViewController:self];
[self presentModalViewController:controller animated:YES];
}
}
- (void) messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
[self dismissModalViewControllerAnimated:YES];
[[UIApplication sharedApplication].delegate.window.rootViewController removeFromParentViewController];
}
(I know the call to sharedApplication is a bit hacky, but it will suffice for now. the rootViewController is a UINavigationController which has its root controller set to the table view controller)
I am invoking the SMS VC from the table VC like so:
- (void ) viewDidAppear:(BOOL)animated
{
static BOOL presentedSMSVC = NO;
if (!presentedSMSVC)
{
SendSMSController *sendSMS = [[SendSMSController alloc] init];
[sendSMS sendSMSWithBody:#"body"
andRecipients:[NSArray arrayWithObject:#"123456789"]];
presentedRegisterVC = YES;
}
}
The problem is that after the user sends the SMS the table view cells are not displaying.
I thought maybe I need to refresh the view/table so I added a protocol callback from the 2nd VC to the first which gets invoked when the user sends the SMS, and then within the callback call [self.tableView reloadData] But it made no difference.
So I got rid of the intermediary class and edited the table view to display the SMS view directly like this:
- (void ) viewDidAppear:(BOOL)animated
{
static BOOL presentedRegisterVC = NO;
if (!presentedRegisterVC)
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if ([MFMessageComposeViewController canSendText])
{
controller.messageComposeDelegate = self;
controller.body = #"body";
controller.recipients = [NSArray arrayWithObject:#"12345678"];
[self presentModalViewController:controller animated:NO];
}
}
}
- (void) messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
[self dismissModalViewControllerAnimated:NO];
}
But now the MFMessageComposeViewController doesn't dismiss (although messageComposeViewController:didFinishWithResult: does get called)
What is the problem with both approaches? Thanks
For the second variant, I changed to:
[self presentViewController: controller animated: YES completion:nil];
[self dismissViewControllerAnimated:YES completion:nil];
And that worked, haven't tried applying to the first method.
I faced a similar UI issue.
My case was: The controller, let's say controller A, in which I had written the code to present and dismiss the MFMessageComposeController, was not being used directly as the active controller rather I was using A.view as a subview over another controller, say controller B. So writing the following was distorting the view:
[self presentViewController:composeVC animated:YES completion:nil];
But then writing the following solved my issue:
[self.customTabbarNavigation presentViewController:composeVC animated:YES completion:nil];
The customTabbarNavigation, was the controller B, ans was actually the navigation controller which was active when controller A's view was visible.
Same change had to be made for dismissing the composeVC.

Resources