I have a universal app that displays buttons inside an actionsheet.
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:[dataObj.preferences objectForKey:#"appts_name"], #"Reserve", nil];
[actionSheet showInView:self.view];
On an iPad that automatically gets changed to a UIPopoverController. This displays and acts fine, however if I have the above popover being displayed and change orientation on the iPad then tap one of the buttons, it crashes in that buttons method where I am wanting to display another popover, saying that
-[UIPopoverController presentPopoverFromRect:inView:permittedArrowDirections:animated:]: Popovers cannot be presented from a view which does not have a window.
If I do not rotate the iPad and just tap a button it executes the same code just fine.
UINavigationController *navBar = [[UINavigationController alloc] initWithRootViewController:addItemView];
popOver = [[UIPopoverController alloc] initWithContentViewController:navBar];
if (viewPopover) {
if (self.view.window != nil) {
CLS_LOG(#"Rect: %# - View: %#", NSStringFromCGRect(rectPopover), viewPopover);
[popOver presentPopoverFromRect:rectPopover inView:viewPopover permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
} else {
// We should NEVER get here but just incase. I don't want the app to crash.
CLS_LOG(#"No viewPopover or rectPopover - %# - %#", viewPopover, NSStringFromCGRect(rectPopover));
}
Log from the CLS_LOG
-[AppointmentViewController showAppointmentAdd] line 148 $ Rect: {{341.333, 592}, {1, 1}} - View: <UIScrollView: 0xc8c5d40; frame = (1044 0; 768 872); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0xc8c7780>; contentOffset: {-0, 188}>
rectPopover and viewPopover are legit. Why is the popOver crashing saying it isn't in a window, but only when I rotate the device?
EDIT:
I found out it is being caused because after orientation change, I am reloading the view to account for the new sizes. It seems this takes precedence in the window. It also only seems to affect the UIActionSheet.
Have you tried tried redisplaying the popover after rotation?
You know when the rotation is occurring (willRotateToInterfaceOrientation:), and then you can redisplay the popover controller according to it's new anchor point.
Related
I have a piece of code pointing a UIPopoverController to a menu item in iOS 8/9, it was working in iOS7 and in fact it's in production on the App Store. For some reason, it doesn't show properly when I tried to test the code on iOS 8/9.
For some reason, the iOS framework inserts the black shadow thing about 75% of the screen. It's like it thinks the device is in portrait mode. My app is always in the landscape mode. Portrait is not considered.
When I click on the area outside the dark shadow, I get:
_UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: <UIWindow: 0x1355065a0; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x174645520>; layer = <UIWindowLayer: 0x174223920>>
I suspect something is making the framework believes the app is running portrait. The error message above is saying the area outside the dark shadow has no respondent to my clicking action. It's my suspicion, I'm not 100% sure.
and the code:
-(void) showActionControllerByPopover:(UIViewController *)actionController item:(UIBarButtonItem *)item
{
UINavigationController * const navController = [[UINavigationController alloc] initWithRootViewController:actionController];
[navController.navigationBar setBarStyle:UIBarStyleDefault];
[_popController dismissPopoverAnimated:YES];
_popController = [[UIPopoverController alloc] initWithContentViewController:navController];
[_popController setDelegate:self];
[_popController setPopoverContentSize:CGSizeMake(320, 768)];
[_popController presentPopoverFromBarButtonItem:item
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
I have the following code for a UIPopoverController. It is working fine in iOS 7. However, in iOS 8, the popover becomes full-screen which I do not want. How do I keep the popover from filling the entire screen in iOS8?
CGRect buttonFrame = [[[[[self tabBarController] tabBar] subviews] objectAtIndex:index+1] frame];
popover = [[UIPopoverController alloc]initWithContentViewController:viewmapmenu] ;
popover.popoverContentSize = CGSizeMake(95, 128.0) ;
popover.delegate = self ;
[popover presentPopoverFromRect:buttonFrame inView:self.tabBarController.tabBar permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES] ;
Try to add this delegate method.
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller;{
return UIModalPresentationNone;
}
See, here is the situation. if you are presenting the popover in iPhone then it will not work in iOS 8 as Apple has completely restricted it even if it was previously working. Now you cannot present popover in iPhone as all the access to the private methods of UIPopover is blocked.
You can look into the FPopover Library in github to use popover in iPhone:-
https://github.com/50pixels/FPPopover
I'm using TheSidebarController to implement add a sliding menu into an iOS application. This is the library I'm using, but I've found the same issue in other libraries, like ECSlidingViewController, etc. They essentially work by adding multiple view controllers onto a containing view controller, nothing too crazy.
The issue is, when you make the app a landscape app, all the screens in the container- the menu, the content screen- seem to think they're in portrait mode, and get cut off half way. You can see the issue in this screenshot where the table is cut off:
http://imgur.com/xD5MUei
I've been trying to get this to work in any way I can, and no luck.
The library I'm using + example project can be found here:
https://github.com/jondanao/TheSidebarController
Any help is greatly appreciated :)
EDIT: people are saying I can stretch the table out to make it look normal, but this just masks the underlying problem, which is the app and/or the screens still think they're in portrait orientation. As a quick example, if I take the example project, and in LeftViewController substitute the following code:
- (void)dismissThisViewController
{
UIViewController* vc = [[UIViewController alloc] init];
UINavigationController* pulldown = [[UINavigationController alloc] initWithRootViewController:vc];
pulldown.view.frame = CGRectMake(pulldown.view.frame.origin.x, -[[UIApplication sharedApplication] delegate].window.frame.size.height,
pulldown.view.frame.size.width, pulldown.view.frame.size.height);
[[[UIApplication sharedApplication] delegate].window addSubview:pulldown.view];
[UIView animateWithDuration:.5 animations:^{
pulldown.view.frame = CGRectMake(pulldown.view.frame.origin.x, 0,
pulldown.view.frame.size.width, pulldown.view.frame.size.height);
} completion:^(BOOL finished) {
;
}];
}
The viewcontroller comes in sideways, not from the top.
This was a strange one... I had to set the frame of the content view controller, which made sense, but then I had to reset it every time the content was refreshed:
- (void)setContentViewController:(UIViewController *)contentViewController
{
// Old View Controller
UIViewController *oldViewController = self.contentViewController;
[oldViewController willMoveToParentViewController:nil];
[oldViewController.view removeFromSuperview];
[oldViewController removeFromParentViewController];
// New View Controller
UIViewController *newViewController = contentViewController;
[self.contentContainerViewController addChildViewController:newViewController];
[self.contentContainerViewController.view addSubview:newViewController.view];
[newViewController didMoveToParentViewController:self.contentContainerViewController];
_contentViewController = newViewController;
if ([DeviceDetection isDeviceiPad]) {
_contentViewController.view.frame = CGRectMake(0, 0, 1024, 768);
}
}
Did you check if it's has something to do with the new interface orientation?
https://developer.apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html
chapter -> Supporting New Screen Sizes and Scales
In CenterViewController.h make the class a subclass of a UITableViewController instead.
Then comment out [self.view addSubview:self.tableView]; in CenterViewController.m.
Done!
In centerViewController.m, when you create the tableview, add this line:
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
I created a modal dialog in my viewController.
dialogViewController *dialog = [[dialogViewController alloc] init];
dialog.modalPresentationStyle = UIModalPresentationFormSheet;
dialog.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
dialog.indexPath = indexPath;
dialog.campaignArray = self.campaignArray;
dialog.view.superview.frame = CGRectMake(dialog.view.superview.frame.origin.x+250, dialog.view.superview.frame.origin.y, dialog.view.superview.frame.size.width-250, dialog.view.superview.frame.size.height);
[self presentViewController:dialog animated:YES completion:nil];
The above changes the width but not the x position of the modal dialog. It works in the modalDialog but then user can see it being resized.
If you want to use
UIModalPresentationFormSheet
the controller will be centred. There is very specific formatting included in this. If you want anything different, you will have to build your own.
The width and height of the presented view are smaller than those of the screen and the view is centered onscreen. If the device is in a landscape orientation and the keyboard is visible, the position of the view is adjusted upward so the view remains visible. All uncovered areas are dimmed to prevent the user from interacting with them.
Try this:
dialogViewController *dialog = [[dialogViewController alloc] init];
dialog.modalPresentationStyle = UIModalPresentationFormSheet;
dialog.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
dialog.indexPath = indexPath;
dialog.campaignArray = self.campaignArray;
[self presentViewController:dialog animated:YES completion:nil];
CGRect dlgFrame = dialog.view.superview.frame;
dlgFrame.size.width -= 250.0;
dialog.view.superview.frame = dlgFrame;
My app is iPad only, and supports only Landscape View.
I have a UIImagePickerController which loads the Camera.
I set it up with the following code:
m_Pickercontroller=[[UIImagePickerController alloc] init ];
m_Pickercontroller.sourceType = UIImagePickerControllerSourceTypeCamera;
m_Pickercontroller.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
m_Pickercontroller.cameraDevice = UIImagePickerControllerCameraDeviceRear;
m_Pickercontroller.showsCameraControls = YES;
m_Pickercontroller.navigationBarHidden = YES;
m_Pickercontroller.toolbarHidden = YES;
m_Pickercontroller.wantsFullScreenLayout = YES;
m_Pickercontroller.allowsEditing=NO;
It is presented with [self presentViewController:m_Pickercontroller animated:YES completion:nil]; I have also tried with a Modal and get the same result.
This occurs on first open of the view only. If you reopen the camera or retake the picture, it goes away.
I have also tried setting the m_Pickercontroller frame size, both before and after it is loaded.
Here is what it looks like, black area is empty, white area is the camera preview. Ignore the white line overlay, that is part of the app.
Ok, so this makes no since whatsoever but what was causing this was the animation:yes
I changed [self presentViewController:m_Pickercontroller animated:YES completion:nil]
to [self presentViewController:m_Pickercontroller animated:NO completion:nil]
and this issue has fixed itself. apparently iOS does not resize the camera preview after animating the view in.