presentModalViewController - ViewController automatically disappears after presenting - iphone

I am currently developing an iPhone App for my company and i ran into a strange thing.
My View Hierachy looks like this:
UITabBarController containing 5 Tabs with every Tab containing a UINAvigationController.
So far everything works perfect.
Now i want to present a modal View controller via the presentModalViewController method on the
UITabBarController using this lines of code:
-(void)callFilterOptions
{
FilterOptionsView *filterView = [[FilterOptionsView alloc] init];
[filterView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self.tabBarController presentModalViewController:filterView animated:TRUE];
}
The FilterOptionsView is a normal UIViewController containing nothing but a black background at the
moment.
What happens is that the view is presented and after a couple of seconds misteriously disappears.
Why is this happening? At no Point i am calling the dismissModalViewController method.
I already ran into this problem when presenting a mailcomposer.
greetings,
Florian

UINavigationController *myNavController = [self navigationController];
[myNavController presentModalViewController:filterView animated:TRUE];
or a better approach might be:
UIApplication *myApp = [UIApplication sharedApplication];
noIBAppDelegate*appDelegate = (noIBAppDelegate*)myApp.delegate;
[appDelegate.tabBarController presentModalViewController:filterView animated:YES];
to dismiss:
UIApplication *myApp = [UIApplication sharedApplication];
noIBAppDelegate*appDelegate = (noIBAppDelegate*)myApp.delegate;
[appDelegate.tabBarController dismissModalViewControllerAnimated:YES];
p.s. I recommend not naming a view controller "filterView" it would be better named "filterViewController"

Related

iOS: Dismissing and Presenting ModalViewController without access to its Parent ViewController

Background: I would like to dismiss a modalView that I have presented earlier and right away present the same viewController that I just dismissed with new information.
Problem: I have not been very successful in doing so without an explicit pointer to the parent ViewController that presented the first ViewController modally. I am trying to write this class that works without messing around with the previous viewController's code.
Possible lead: There are couple of things I have been experimenting with:
1.) Trying to get access to the parent ViewController, which at this time I don't know how to.
2.) Once access to the parent is gained, I can simply apply the following code:
UIViewController* toPresentViewController = [[UIViewController alloc] init];
[self dismissViewControllerAnimated:YES completion:^{
[parentViewControllerAccessor presentModalViewController:toPresentViewController animated:YES];
}];
In theory this should work given the access to parent viewController. I am open to other ways of doing this.
Assumption: You do not have permission to change any code in the parent ViewController.
Your code looks like it should work. If you are using iOS 5 there is a UIViewController property called presentingViewController.
#property(nonatomic, readonly) UIViewController *presentingViewController;
So you can use this property to get the view controller that presented your modal controller.
Note: In iOS 4 parentViewController would be set to the presenting controller, so if you are supporting both iOS 4 and 5 you will have to check the OS version first to decide which property to access. In iOS 5 Apple have fixed this so that parentViewController is now exclusively used for the parent of contained view controllers (see the section on Implementing a Container View Controller in the UIViewController documentation).
Edit: Regarding accessing self.presentingViewController from within the block: By the time the block is called (after the modal view controller is dismissed) the presentingViewController property may get set to nil. Remember that self.presentingViewController inside the block gives the value of the property when the block is executed, not when it was created. To protect against this do the following:
UIViewController* toPresentViewController = [[UIViewController alloc] init];
UIViewController* presentingViewController = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^
{
[presentingViewController presentModalViewController:toPresentViewController animated:YES];
}];
This is necessary not because self is gone/dismissed (it is safely retained by the block), but because it is no longer presented, therefore its presentingViewController is now nil. It is not necessary to store the presentingViewController anywhere else, the local variable is fine because it will be retained by the block.
You could accomplish this using notifications.
For example, fire this notification from outside the modal view when you want it to be dismissed:
[[NSNotificationCenter defaultCenter] postNotificationName:#"dismissModalView"
object:nil
userInfo:nil];
And then handle that notification inside your modal view:
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(dismissMe:)
name:#"dismissModalView"
object:nil];
}
- (void)dismissMe:(NSNotification)notification {
// dismiss it here.
}
the solution for ios5:
-(void)didDismissModalView:(id)sender {
// Dismiss the modal view controller
int sold=0;
if(sold==0){
//Cash_sold.delegate = self;
// Cash_sold.user_amount.text=[NSString stringWithFormat:#"%d",somme];
Cash_sold = [[CashSoldview alloc] initWithNibName:#"CashSoldview" bundle:nil];
CGRect fram1 = CGRectMake(200,20,400,400);
Cash_sold.view.superview.frame = fram1;
Cash_sold.view.frame=fram1;
Cash_sold.modalTransitionStyle= UIModalTransitionStyleCoverVertical;
Cash_sold.modalPresentationStyle=UIModalPresentationFormSheet;
UIViewController* presentingViewController = self.parentViewController;
[self dismissViewControllerAnimated:YES completion:^
{
[presentingViewController presentModalViewController:Cash_sold animated:YES];
}];
}
}
Try the following code:
[self dismissViewControllerAnimated:NO
completion:^{
// instantiate and initialize the new controller
MyViewController *newViewController = [[MyViewController alloc] init];
[[self presentingViewController] presentViewController:newViewController
animated:NO
completion:nil];
}];

ViewController loaded in the Background after creating it from MapKit (didSelectAnnotationView)

I'm trying to create from the delegate method didSelectAnnotationView a ViewController.
I've got following Code:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
DestinationViewController *destinationViewController = [[DestinationViewController alloc] init];
NSNumber *mynumberId = [NSNumber numberWithInt:1];
destinationViewController.mynumberId = mynumberId;
[self.navigationController pushViewController:destinationViewController animated:YES];
}
After I tap on a Annotation I'm seeing just a black ViewController Screen with the Navigation Bar. But the Log tells me that everything is loaded correctly. So it seems like my Destination ViewController is somewhere in the background.
If you create your VC from a Nib, you need to use initWithNibName: rather than just init.
If you load the view programmatically, you need to check your viewDidLoad method.
It is not a mapKit issue, but you are not loading your VC and its view the way you should.
I've researched on the Apple Developer Site and found the answer for my question. I'm using Storyboards, and here the code snippet from Apple:
- (IBAction)presentSpecialViewController:(id)sender {
UIStoryboard *storyboard = self.storyboard;
SpecialViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"SpecialViewController"];
// configure the new view controller explicitly here.
[self presentViewController:svc animated:YES completion:nil];
}
and here the Link where you can find more Info about View Controller Programming:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/UsingViewControllersinYourApplication/UsingViewControllersinYourApplication.html

DismissmodalViewController donot remove the modal View

I have been figuring out this since yesterday but have not got that correct yet.
I have added the modalviewcontroller for my loading view controller on top of my tab bar controller and it works fine.
Added the code in app Delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
[navController.navigationBar setTintColor:[UIColor blackColor]];
[window addSubview:rootController.view];
[window makeKeyAndVisible];
LoadingViewController *lvc = [[LoadingViewController alloc] initWithNibName:#"LoadingView" bundle:nil];
// Delegate added here
lvc.loadingDelegate = self;
[rootController presentModalViewController:lvc animated:YES];
[self URL];
[lvc release];
return TRUE;
}
Now I do my parsing and when its done I call the following code in different view name XMLParsingView.m where the parsing got over.
- (void)handleLoadedApps
{
LoadingViewController *loading = [[[LoadingViewController alloc] init] autorelease];
//delegating to let the load view controller know to dimiss itself by defining disappear method in protocol
[loading.loadingDelegate disappear];
}
and in loading view controller I have method which calls dismissModalViewControlAnimated:
-(void)disappear{
[activity stopAnimating];
[activity removeFromSuperview];
[self removeFromSuperview];
[self dismissModalViewControllerAnimated:YES];
}
But for some reason it will never remove the view and not load it back to my tab bar controller.
Really need help here if any one have come across such issues.
Sagos
In your code you seem to create, without a nib, a new LoadingViewController and immediately go and dismiss it. In your app delegate you create your first loadingViewController with a nib, present it modally on rootController and then release it. Since you want to dismiss it outside your app delegate you have
3 choices, (hardest to fastest and most sane)
a) Key-Value-Observing on a property of XMLParsingView from LoadingViewController to remove itself when the task finishes.
b) Use delegation to inform the LoadingViewController when the task finishes to dismiss itself.
c) Fetch your rootController from your [[UIApplication sharedApplication] delegate], which means you must expose rootController as a property or through a method, and make rootController dismiss your modal.
You need to call dismissModalViewControllerAnimated on the rootViewController, not the loading view controller.

After dismissModalViewControllerAnimated: my tabbar disappears

I have an app which consists of three layers of view controllers: UITabBarController => UINavigationController => UIViewController. They are all generated in code rather than using IB. The tab bar is on the bottom as per the usual design guidelines. In my UIViewController I am using this code to present the modalViewController:
myModalVC = [[MyModalViewController alloc] init];
[self.navigationController presentModalViewController:myModalVC animated:YES];
This work fine and the modal view controller pops up and covers the entire screen.
However when a button is pressed within the modal view controller, I run this:
[self dismissModalViewControllerAnimated:YES];
And the modal view controller animates away. However I can see the original UIViewcontroller view but the tab bar disappears completely. I've googled a lot but I can't find anyone that has this same problem.
You should delegate your modal view controller to your parent view controller. [self dismissModalViewControllerAnimated:YES]; should be done by the delegate and not the modal view itself, parent view are responsible for dismissing the modal view.
Actually I found this by googling a bit more. I made my tab bar controller a property of the app delegate and when it presents the modal vc, it does this
UIApplication *myApp = [UIApplication sharedApplication];
noIBAppDelegate*appDelegate = (noIBAppDelegate*)myApp.delegate;
[appDelegate.tabBarController presentModalViewController:myModalVC animated:YES];
Then it dismisses it by this bit of code
UIApplication *myApp = [UIApplication sharedApplication];
noIBAppDelegate*appDelegate = (noIBAppDelegate*)myApp.delegate;
[appDelegate.tabBarController dismissModalViewControllerAnimated:YES];
This fixes the the tab bar disappearing.
Try
[self.navigationController dismissModalViewControllerAnimated:YES];
Thanks for your answer! I had the same problem, but I'm writing in Swift, so thought I'd include my solution that I figured out from looking at yours. I only had to use these two lines to fix the problem. Nothing else was needed.
tabBarController?.presentViewController(viewController, animated: true, completion: nil)
and
tabBarController?.dismissViewControllerAnimated(true, completion: nil)
I should also mention that the line: tabBarController?.delegate = self, is in the viewDidLoad function of my NavigationController.

viewWillAppear not invoked when presenting the viewController modally (iOS)

I have an issue, viewWillAppear method in the UIViewController which is added to the screen by presentModalViewController method does not "go into" viewWillAppear method. Only time this method is invoked is together with the viewDidLoad, the first time.
- (IBAction)openModal:(id)sender {
if (self.nvc == nil) {
ModalViewController *vc = [[ModalViewController alloc] init];
self.nvc = vc;
[vc release];
}
self.nvc.segmentedIndex = [[self.navigationController.viewControllers objectAtIndex:0] index];
[self presentModalViewController:self.nvc animated:YES];
}
The property is of type retain.
Thanks in advance.
right, it works different and it now goes into viewWillAppear only once. So if you want to change the appearance of your view after dismissing a modal view you should do it using a modal delegate pattern. See the link:
http://useyourloaf.com/blog/2010/5/3/ipad-modal-view-controllers.html
Though it's for iPad, but you can get the idea. In the latest iOS versions it works the same.
Hope it helps