I have a problem with the function call:
[self dismissModalViewControllerAnimated:YES];
In MainViewController, I can launch a image picker and dismiss as usual by clicking the cancel button.
(IBAction) LaunchInMain:(id)sender{
MainAppDelegate *app = (MainAppDelegate *)[[UIApplication sharedApplication] delegate];
//elcPicker is a customized image picker
[app.viewController presentModalViewController:elcPicker animated:YES];
[elcPicker release];
[albumController release];
- (void)elcImagePickerControllerDidCancel:(ELCImagePickerController *)picker {
[self dismissModalViewControllerAnimated:YES];
}
Now, instead of launching it direct it in Main, I add a subview first and launch the image picker from the subview using the same launch method.
Problem:
The image picker cannot be dismissed and the subview cannot be shown again. So the screen will remain at the image picker no matter what I click.
I have been trying with some other calls like without any success:
[self dismissModalViewControllerAnimated:YES];
I am happy with any help or idea. If you think more information should be provided, I can add more codes.
May be try
[app.viewController dismissModalViewControllerAnimated:YES];
Hope this helps.
This may work for you:
[self.view dismissModalViewControllerAnimated:YES];
This works if you are presenting a modal view from a UISplitViewController. It can also be applied in so many other ways...
First, create an instance in your .h file for your appDelegate, (AppDelegate_iPad *appDelegate) then put this in your viewDidLoad or comparable method:
ipadDelegate = (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];
Now, present the first modal view like this:
YOURVC *vc = [[YOURVC alloc] initWithNibName:#"YOURVC" bundle:nil];
[ipadDelegate.splitViewController presentModalViewController:vc animated:YES];
[vc release];
Say you have a subview, like a UITableView, and want to dismiss the modal from the didSelectRowAtIndexPath. All you have to do to dismiss your modal with a subview is create another ipadDelegate instance inside your subview's .h (if needed), reference the [[UIApplication sharedApplication] delegate] again, and dismiss:
[ipadAppDelegate.splitViewController dismissModalViewControllerAnimated:YES];
Essentially, as long-winded as it may be, use your appDelegate's controller to present and dismiss the the modal if you need to maintain a persistent reference to the presentingViewController...because all the things above just don't work in my case.
If you're presenting with your ipadDelegate, make sure you check the mode of presentation in your MainWindow_iPad.xib. Your "Transition Style" should be "Cover Vertical" and "Presentation" should be "Current Context" or your modal may present behind other views.
Related
I am calling a UIImagePickerController (sourceTypeCamera) as a modalViewController from my MainViewController.
However, the UIImagePickerController doesn't fill the screen on top, as the image attached shows.
Any idea what can be causing this, and how to fix?
After lots of tries, I discovered that calling presentViewController from the [[[[UIApplication sharedApplication] delegate] window] rootViewController] solved the problem.
You should change the frame property of imagePickerController. when intializing I.e.
imagePickerController.view.frame.origin.y = 20;
Some code would be helpful.
If relevant, try setting the bounds property instead of the frame property.
In my application in a viewcontroller which is inside navigationController - i'm doing simply like this:
UIImagePickerController* imagePickerController_;
imagePickerController_.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:imagePickerController_ animated:YES];
and
#interface CustomViewController : UIViewController <UIImagePickerControllerDelegate>
Works without problems. If You still have problems, then can you please share some code? what kind of navigation structure your application have (tabbarcontroller, navigationcontroller, .. ?)?, how do you present imagepickercontroller?
There is a boolean on UIViewController that may be of use to you: wantsFullScreenLayout. According to the docs, this is:
A Boolean value indicating whether the view should underlap the status bar.
I've had several issues, especially on iOS 5, with views underlapping the status bar, especially when presented modally. The best thing I have found is to set this value to YES, and manually lay out your view below the status bar. FYI, the status bar has a height of 20.
Call
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
Before calling
[self presentModalViewController:picker animated:YES]
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self.view addSubview:imagePicker.view];
[imagePicker viewWillAppear:YES];
[imagePicker viewDidAppear:YES];
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
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];
}];
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.
I have a UINavigationController and I have seperate UIViews that I switch between using a UISegmentControl. On switching the views, I add the view as a subview to my navigation controller's view:
[self.view addSubview:segmentTab1.view];
and
[self.view addSubview:segmentTab2.view];
Then, in the subViews, each has a UITableView, but my issue is, that I am unable to push a new viewController into view in the didSelectRowAtIndexPath method.
The method is called correctly and by setting breakpoints, I can see the method for pushing the view gets called as well, but nothing happens. This is my code for pushing it:
[self.navigationController pushViewController:detailsViewController animated:YES];
I also tried
[super.navigationController pushViewController:detailsViewController animated:YES];
What am I doing wrong - or is is just not possible to do it with a subview?
When you call -pushViewController, which view controller is self? If you are calling that from within one of your tab subviews, self likely doesn't have a reference to the navigation controller from the top level view that you added it to. You can verify this by getting the memory address of the navigation controller from within the top level view and comparing it to what you have in the subview. Obviously if it's nil or doesn't match, then that's your problem.
You only get a navigation controller "for free" when it's been added to the navigation stack itself with -pushViewController which your subviews haven't been added that way.
I had a similar issue when implementing a common header for all the views
After many tries , i have fixed it by this -
In all the viewController
- (void)viewWillAppear:(BOOL)animated {
[self.view addSubview:[[(NavAppAppDelegate *)[[UIApplication sharedApplication] delegate] headerview] view]];
[[(NavAppAppDelegate *)[[UIApplication sharedApplication] delegate] headerview] viewWillAppear:YES];
}
I have referred following post to implement the header view
Common XIB in multiple View Controller in iPhone
[self.view addSubview:[[(NavAppAppDelegate *)[[UIApplication sharedApplication] delegate] headerview] view]]; // line will load the header subview
[[(NavAppAppDelegate *)[[UIApplication sharedApplication] delegate] headerview] viewWillAppear:YES]; // this is to call the viewWillAppear method of HeaderController where we can write code to check the user is logged or not and change the login button to logout button etc ..
Instead of
[self.view addSubview:segmentTab1.view];
and
[self.view addSubview:segmentTab2.view];
you may use
[self pushViewController: segmentTab1 animated: NO];
and
[self pushViewController: segmentTab2 animated: NO];
to add your viewControllers to the navigation hierarchy, and make [super.navigationController pushViewController:detailsViewController animated:YES]; work.
It is not entirely clear to me what your view hierarchy is, but in general if your navigation controllers view is not the first subview of a window or an element of one of Apple's collection views (either another navigation view controller's content view or a tab controller's content view) it won't work correctly.
One possibility, if you are not averse to singletons, is to make your product's UINavigationController object be a singleton, accessible from (for example) your application delegate.
You would invoke it thus:
[[((MyApplicationDelegate*)[UIApplication delegate]) navController]
pushViewController: viewControllerToPush animated: YES];
where within MyApplicationDelegate, navController returns the singleton object.
LogEntryDetailViewController *leController = [[LogEntryDetailViewController alloc] initWithNibName:#"LogEntryDetailView" bundle:[NSBundle mainBundle]];
[leController setTitle:[NSString stringWithFormat:#"%#", [logEntriesArray objectAtIndex:row]]];
[[self navigationController] pushViewController:leController animated:NO];
[leController release], leController = nil;
In my app I have a tabBarController and in it a navigationController. One of my view controllers is a TableViewController and under the navigationBar i added a uiView as a subview to the view like this:
rectangleInfo = [[UIView alloc] initWithFrame:CGRectMake(0,0,[[UIScreen mainScreen] applicationFrame].size.width,26)]; rectangleInfo.autoresizingMask = (UIViewAutoresizingFlexibleWidth); rectangleInfo.backgroundColor = [UIColor darkGrayColor]; [self.view addSubview: rectangleInfo];
when I click on a cell in the tableView I push an UIViewController like this:
[feedViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[[self navigationController] presentModalViewController:feedViewController animated:YES];
After i pop the modal view for a couple of times with it from the tableViewNavigationController disappears the rectangleInfo UIView.
I pop my modalview like this:
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
[self setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self dismissModalViewControllerAnimated:YES];
any idea why that subview (rectangleInfo) of the tableViewController dissapears after i remove the modal view from the superview?
thank you in advance.
I'm curious as to what you are trying to do with your rectangleInfo view? By the size of it, it looks like you are trying to mimic the status bar. Why? You can just hide the status bar if you want.
Another thing you can try is to create the UIView visually in Interface Builder. Don't actually add it to your main view, but create it as a separate UIView in the XIB with the appropriate size, etc. Then create an outlet for it in Xcode and connect it. Next, add it as a subview in code when your view controller loads. See if that makes a difference. This is especially strange since you say it only disappears after popping it several times. Do you get the same problem if you push and pop the non-modal way, e.g.:
[[self navigationController] pushViewController:feedViewController animated:YES];
[[self navigationController] popViewControllerAnimated:YES];
i solved the problem by implementing correctly the viewDidLoad and viewDidUnload methods for creating and releasing my subviews.