UIPopoverController disappears when ipad orientation changes - iphone

Popover appears properly when I click on button.
When orientation changes then it disappears & leave a black topbar.
Below is the reference image.
Can anyone suggest, why it is happening?
My Code:
EBFirstViewController *firstViewController = [[EBFirstViewController alloc]init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
navigationController.delegate = self;
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
self.popoverController = popover;
popoverController.delegate = self;
[popoverController setPopoverContentSize:CGSizeMake(320.0f, 527.0f)];
[popoverController presentPopoverFromRect:settingsBtn.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

For That following code help to solve your problem.
- (void)application:(UIApplication *)application willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration {
// a cheat, so that we can dismiss all our popovers, if they're open.
if (ObjPopover) {
// if we're actually showing the menu, and not the about box, close out any active menu dialogs too
if (menuPopoverVC && menuPopoverVC == ObjPopover.contentViewController)
[menuPopoverVC.popoverController dismissPopoverAnimated:YES];
[menuPopoverPC dismissPopoverAnimated:YES];
menuPopoverPC = nil;
}
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
// the user (not us) has dismissed the popover, let's cleanup.
ObjPopover = nil;
}

Related

Make Popover Background Black in Interface Builder

I've successfully hooked up several popover views in interface builder. I've tried to make the background black by setting the view background color to black, but I am still getting a white arrow on the popover itself and white artifacts on the 4 rounded corners.
Please see the screenshot.
What can I do to make the background totally black in interface builder?
I appreciate the answer below but I still can't quite get it to work - here is my code:
// Show the satellite Ephemeris
if ( itemIndex == 1 ) {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSLog(#"This is an iPad - Creating popover!");
EphemerisDataView *ephemView = [[EphemerisDataView alloc] init];
UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:ephemView];
[popOver setPopoverBackgroundViewClass:[DDPopoverBackgroundView class]];
[popOver.popoverBackgroundViewClass setTintColor:[UIColor blackColor]];
CGSize size = CGSizeMake(320, 480); // size of view
popOver.popoverContentSize = size;
[popOver presentPopoverFromRect:self.popOverAnchor.bounds inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
NSLog(#"This is not an iPad - Performing segue...");
// Show the next view
[self performSegueWithIdentifier:#"Ephemeris" sender:self];
}
}
You cannot customize that arrow by IB. You will need a totally customized popover for you. Plenty of them are available on git. But If you want to use default one then it is not possible to customize that arrow as well.
Do it like this:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSLog(#"This is an iPad - Creating popover!");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName: #"MainStoryboard_iPad" bundle:[NSBundle mainBundle]];
EphemerisDataView *ephemView = [storyboard instantiateViewControllerWithIdentifier:#"EphemerisDataView"];
UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:ephemView];
self.customPopoverController = popOver;
[popOver setPopoverBackgroundViewClass:[DDPopoverBackgroundView class]];
[popOver.popoverBackgroundViewClass setTintColor:[UIColor blackColor]];
popOver.delegate = self;
CGSize size = CGSizeMake(320, 480); // size of view
popOver.popoverContentSize = size;
[popOver presentPopoverFromRect:self.popOverAnchor.bounds inView:self.popOverAnchor
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
NSLog(#"This is not an iPad - Performing segue...");
// Show the next view
[self performSegueWithIdentifier:#"Ephemeris" sender:self];
}

How can i use popover controller in UIPageViewController?

Can i use the popover controller to get back to previous view controllers in page view controller. Is there any method to do so.
This code i am trying.
-(void)goNext
{
Vcontr = [self.pageController.viewControllers objectAtIndex:0];
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:pageController];
if(popoverController == nil){ //make sure popover isn't displayed more than once in the view
popoverController = [[UIPopoverController alloc] initWithContentViewController:pageController];
}
[popoverController presentPopoverFromRect:self.view.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
popoverController.delegate = self;
}
Here are some tutorials:
iPad for iPhone Developers 101: UIPopoverController Tutorial
iPad UIPopoverController Video
and read Apple developers
and you can find sample code by Apple developers
UIPopoverController *popoverController ;///defin this in the .h
if(popoverController == nil){ //make sure popover isn't displayed more than once in the view
popoverController = [[UIPopoverController alloc] initWithContentViewController:yourPageViewController];
}
[popoverController presentPopoverFromRect:self.view.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
popoverController.delegate = self;
}

Unable to present modal view controller in didFinishWithResult

Is it possible to present Modal view controller in didFinishWithResult?
I have an iPad application with 3 views Home,Start and Login. Start and Login modal views can be launched using start and login buttons in home view.
If clicked on login button, after successful login operation (didFinishWithResult) in login view I am able to dismiss the login view and but i am not able to launch the start view. But the control stays back on home view.
I am not getting any error for the above scenario.
Appdeligate.m :
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
HomeViewController * homeview=[[HomeViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:homeview];
self.rootViewController = navigationController;
[navigationController setNavigationBarHidden:YES];
self.rootViewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[self.window addSubview:self.rootViewController.view];
[window makeKeyAndVisible];
Below is the method in the home view which Present the login modal view
Presenting Login Modal View
LoginViewController * vc1 = [LoginViewController loginViewControllerWithNavBar:YES];
vc1.boxLoginDelegate = self;
[self presentModalViewController:vc1 animated:YES];
Note : LoginVeiwController is Modal view controller which is presented
by HomeViewController. Is it right way to launch/present another modal
view controller (start controller) by dismissing LoginVeiwController
as below. Because whenever the LoginVeiwController dismissed the control stays back on HomeVeiwContrller rather than launching/presenting StartViewController:
Home View :
Below is the method in the home view which will dismisses the login view on successful login and tries to launch the start view.
- (void)loginViewController:(LoginViewController *)loginViewController didFinishWithResult:(LoginResult)result {
[self dismissModalViewControllerAnimated:YES];
startview = [[[startViewController alloc] init] autorelease];
[self.navigationController setNavigationBarHidden:YES];
[self presentModalViewController:startview animated:YES];
}
If I present the StartView directly on button click, it launches nicely, but not on didFinishWithResult
Try like this. I think it will be helpful to you.
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
HomeViewController * homeview=[[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:homeview];
[self.window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES:
you need to restructure this line in your code [self dismissModalViewControllerAnimated:YES]; the reason being when dismiss is called, you loose self context of the controller and hence the line [self presentModalViewController:startview animated:YES]; is not showing any controller further.
to quicktest just comment dismiss line and see for yourself.
use this line when your currentViewController DissMiss then try bellow code...
[self performSelector:#selector(PresentView) withObject:nil afterDelay:0.2];
-(void)PresentView
{
[self.navigationController presentModalViewController:startview animated:YES];
}
hope,this help you....
:)
I guess it's about the animation. While the previous controller is dismissing,
[self presentModalViewController:startview animated:YES];
is called.
You can verify my guess by setting the animation to NO. Or directly use my suggestion to see if it works.
If I am correct, you can set them back to YES.
Besides, instead of directly calling the
[self presentModalViewController:startview animated:YES];
You can try:
[NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:#selector(showController) userInfo:nil repeats:No];
- (void)showController {
[self presentModalViewController:startview animated:YES];
}
edit:
I finally found out how I solve this similar problem before:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[UIView animateWithDuration:0.5
animations:^{
[self dismissModalViewControllerAnimated:YES];
}
completion:^(BOOL finished) {
NSURL *path = [info objectForKey:#"UIImagePickerControllerMediaURL"];
VideoConfirmViewController *videoConfirmCon = [[VideoConfirmViewController alloc]initWithFileURL:path];
[self presentModalViewController:videoConfirmCon animated:YES];
}
];
}
If you don't need compatibility with very old iOS versions it is better to use
-(void)presentViewControllerAnimated:completion:
-(void)dismissViewControllerAnimated:completion:
instead of
-(void)presentModalViewController:animated:
-(void)dismissModalViewController:animated:
In this case
- (void)loginViewController:(LoginViewController *)loginViewController didFinishWithResult:(LoginResult)result
{
[self dismissViewControllerAnimated:YES completion: ^{
startview = [[[startViewController alloc] init] autorelease];
[self.navigationController setNavigationBarHidden:YES];
[self.presentingViewController presentViewControllerAnimated:YES completion:NULL];
}];
}

How can I see lastest subView after clicking popover embedded in NavigationView?

When click button, a popoverView embedded in NavigationView appear.
My code is as follows:
-(IBAction)myStuffPOP:(id)sender
{
if(myStuffListViewController ==nil)
{
myStuffListViewController = [[MyStuffListViewController alloc] init];
}
UINavigationController *navcontroller=[[[UINavigationController alloc] initWithRootViewController:myStuffListViewController] autorelease];
// Here we create popover controller.
mystuffPopoverView = [[UIPopoverController alloc] initWithContentViewController:navcontroller] ;
CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
popoverRect.size.width = MIN(popoverRect.size.width, 100);
popoverRect.size.height = 40;
[mystuffPopoverView presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
[navcontroller setNavigationBarHidden:NO];
}
In NavigationView of PopoverView :
1st subView ---> 2nd SubView ---> 3rd Subview
If I touch 3rd SubView, PopoverView disappears.
My Question is :
When I click button again, I wanna to see lastest View - 3rd SubView not 1st SubView.
Declare UINavigationController *navcontroller; in .h file
Create only onсe navcontroller with your root view controller,
in viewDidLoad method, for example.
- (void)viewDidLoad {
myStuffListViewController = [[MyStuffListViewController alloc] init];
navcontroller=[[UINavigationController alloc] initWithRootViewController:myStuffListViewController]; }
Show UIPopoverController with exist navigation stack
-(IBAction)myStuffPOP:(id)sender {
//Here we create popover controller.
mystuffPopoverView = [[UIPopoverController alloc] initWithContentViewController:navcontroller] ;
CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
popoverRect.size.width = MIN(popoverRect.size.width, 100);
popoverRect.size.height = 40;
[mystuffPopoverView presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
[navcontroller setNavigationBarHidden:NO]; }
Don't forget to release objects
- (void)dealloc {
[myStuffListViewController release];
[navcontroller release];
}
No need to create UINavigationController every time. Save it the same way as MyStuffListViewController
if ( myNavigationController == nil )
myNavigationController = [[[UINavigationController alloc] initWithRootViewController:myStuffListViewController] autorelease];

iphone - cant push modal views after adding subview to window?

Im my application I have the following code, the first bit runs when my application launches, and it presents a login screen in a modal view. With my rootController added to the window before that.
The Modal view will allow a user to log on, view terms and conditions and then if they accept the loadMainApp function is called.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
rootController.delegate = self;
[window addSubview:rootController.view];
LoginViewController *_loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:[NSBundle mainBundle]];
self.loginViewController = _loginViewController;
[_loginViewController release];
UINavigationController *navi = [[[UINavigationController alloc]initWithRootViewController:loginViewController]autorelease];
navi.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[loginViewController release];
[rootController presentModalViewController:navi animated:YES];
[self.window makeKeyAndVisible];
return YES;
}
This next bit is called when the user accepts terms and conditions:
-(void)loadMainApp:(UIView *)fromView{
[fromView removeFromSuperview];
[window addSubview:rootController.view];
rootController.selectedIndex = 2;
rootController.delegate = self;
}
From here I want to be able to use the people picker which is a modal view and I attempt it with this code:
ABPeoplePickerNavigationController *picker =
[[ABPeoplePickerNavigationController alloc]init];
picker.peoplePickerDelegate = self;
[rootController presentModalViewController:picker animated:YES];
[picker release];
But nothing happens, when I try to present a modal view from my rootController nothing displays.
This appears to occur after this code in applicationDidFinishLaunching is run:
LoginViewController *_loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:[NSBundle mainBundle]];
self.loginViewController = _loginViewController;
[_loginViewController release];
UINavigationController *navi = [[[UINavigationController alloc]initWithRootViewController:loginViewController]autorelease];
navi.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[loginViewController release];
[rootController presentModalViewController:navi animated:YES];
[self.window makeKeyAndVisible];
return YES;
If I dont display the login screen at all and instead just add my rootController
rootController.delegate = self;
[window addSubview:rootController.view];
in the applicationDidFinishLaunching function then everything works fine when I go to display the people picker.
Is there something fundamental that I am breaking here or can anyone spot what I may be doing wrong?
Are you dismissing the first modal view controller correctly, via thedismissModalViewControllerAnimated: method? If you're just removing the modal view controller's view from its superview, then probably a lot of paperwork is being left undone by UIKit.
What you should really do is something like this:
Add rootViewController to navigationController. Then add navigationController to the window.
In rootViewController's viewDidLoad method, set loginViewController's delegate to rootViewController and display the LoginViewController's instance as a modal.
When you are done with terms acceptance, do [delegate loginViewControllerFinished];.
Now in rootViewController, handle the loginViewControllerFinished method. This should contain a call to [self dismissModalViewControllerAnimated:YES]; to close the login modal view. Then you should launch ABPeoplePickerNavigationController as a modal view.
In AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Make sure rootViewController is initiated by this point.
UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];
[window addSubview:rootController.view];
[self.window makeKeyAndVisible];
return YES;
}
In RootViewController:
- (void)viewDidLoad {
[super viewDidLoad];
LoginViewController *loginViewController = [[[LoginViewController alloc] initWithNibName:#"LoginView" bundle:nil] autorelease];
loginViewController.delegate = self;
loginViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:loginViewController animated:YES];
}
- (void)loginViewControllerFinished {
[self dismissModalViewControllerAnimated:YES];
// Here we are closing one modal. And showing another after that.
ABPeoplePickerNavigationController *peoplePicker = [[[ABPeoplePickerNavigationController alloc] init] autorelease];
peoplePicker.peoplePickerDelegate = self;
[self presentModalViewController:peoplePicker animated:YES];
}
In LoginViewController:
// Make sure LoginViewController has delegate property in header.
// #property (nonatomic, assign) id delegate;
// And put this in implementation (.m) file. #synthesize delegate.
// Don't put release for delegate, since it's not retained. It's only 'assigned'.
- (void)done {
// Call this when you want to close loginViewController.
[delegate loginViewControllerFinished];
}
Hope this helps.