Centralize popover display in xcode - ios

My popover border was only partially showing the view I wanted to display, so I used the line self.buttonPopoverControllerH1.popoverContentSize = CGSizeMake(1000, 700); to enlarge it.
While it did enlarge the popover, the view still isn't central, and so it is still only partially displayed. Does anyone know how to rectify this?
I can't use autolayout as I'm developing an app for ios 5. I can't link in an image as I don't have enough rep, but
is what I'm talking about. Only half the view is displayed.

Set the rect when you present it..just modify to fit the frame you would like:
CGRect rect = CGRectMake(350,100,100,100);
[yourPopoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

Do you want the popover view to take up most of the screen? If so, you should consider using a Modal View, instead of a popover view. Popover views shouldn't really cover the entire screen.

Related

UIPopoverController backgroundColor back to default after rotation on iOS 8

When setting backgroundColor to [UIColor blackColor] to a UIPopoverController everything is fine and presents correctly on iOS7 and iOS8.
I present it via
[aPopover presentPopoverFromBarButtonItem:self.navigationItem.rightBarButtonItem
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
After a device rotation, the popover backgroundColor is reset to default color (white in this case).
This does not happend in iOS 7. Only on iOS 8
I have already tried with
- (void)presentPopoverFromRect:(CGRect)rect
inView:(UIView *)view
permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections
animated:(BOOL)animated;
and a repositioning using UIPopoverControllerDelegate and the same problem occurs.
Last information : I had this problem only when displaying the popover on a UINavigationBar but not when presenting it on a regular UIView or any UIButton.
Thanks for your help
I also had such problem with popover on iOS8. Besides rotation the background colour was reset when popover changed its size (e.g. when keyboard shows up to edit some text field in the popover).
The key observation is that the issue usually happens with popovers that have its arrow on the very content's edge (and this is the case when presenting popover from UIBarButtonItem of full screen view controller).
Hence my workaround was to modify sourceRect just enough for the popover's arrow to move away from its corner. For example in my particular case I had a bar button item with custom 33x33 view (which was used as sourceView) and the issue was fixed by setting sourceRect to {20, 30, 0, 0} instead of custom view's bounds (though I suppose the exact required offset may depend on popover's size).
For iOS 8.2 (xcode 6.2) : i have problem while open keyboard, popovercontroller becomes white. and after keyboard disappears it is also same as white background.
i use following code to resolve my issue.
[objPopovercontroller presentPopoverFromRect:CGRectOffset(CGRectMake(SCREEN_WIDTH-40, 60, 0, 0), -1, 0)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
// SCREEN_WIDTH = (IS_IPAD?1024:[UIScreen mainScreen].bounds.size.width)
I also had this problem in iOS 9.1. Offsetting the source rect was a good observation and workaround but for me it didn't seem to have an effect until the offset reached 16 or so, which meant the arrow looked somewhat mis-placed.
To avoid this, in the end I used GIKPopoverBackgroundView to provide a custom background view (UIPopoverBackgroundView). I extracted the relevant popover background images from UIKit (see [1] below) to get the same popover shape as iOS 9 and modified their colour to suit my needs.
Heavy-handed, and a bit fiddly setting up the cap insets for the images, but it did the trick.
[1] Use cartool to get _UIPopoverViewBlurMaskBackground* from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework/Artwork.bundle/Assets.car

iPad Modal UIViewControllers position

How do I position this ViewController over the detail view modally? I want it to be right aligned so you can see the navigation portion greyed out.
[self.window addSubview:self.splitViewController.view];
MyModalViewController *modalvc= [MyModalViewController new]; //brevity
modalvc.modalInPopover = YES;
modalvc.modalPresentationStyle = UIModalPresentationStylePageSheet;
modalvc.view.autoresizeMask = UIViewAutoresizeFlexibleRightMargin;
[self.splitViewController presentModalView:modalvc animated:NO];
[self.window makeKeyAndVisible];
I also checked in MyModalViewController if im setting the views mask and I am not, nor is it getting magic values from a Nib.
Adjusting the frame before the present (using modalvc.view.frame) does nothing.
Adjusting the frame after the present seems to yield crazy results, and I only really need it to be half a width over in landscape... portrait is normal behavior.
edit
the picture confused people so I took it out, I dont want the modal view to be the size of the screen, I want to keep it UIModalPresentationStylePageSheet but have its ORIGIN moved right so that it covers the detail view portion in landscape
The modalPresentationStyle is what controls that. You've set it to UIModalPresentationStylePageSheet, which sets the height to the height of the screen, and the width to to the width of the screen in portrait orientation, exactly as in your screenshot.
I think the only way to get full width in landscape is to use UIModalPresentationFullScreen. See the UIViewController reference for more info.
I had a similar problem, and I ended up using a custom view controller that uses a background translucent view and a foreground opaque view that I am able to position anywhere I want by manipulating its frame. It's useful as a lightbox for videos and images.

What is the exact size of UIModalPresentationFormSheet in iPad

I am using following code for displaying a Screen/View Controller.
SearchParams *nxt=[[SearchParams alloc] initWithNibName:#"SearchParams" bundle:nil];
UINavigationController *nvc=[[UINavigationController alloc] initWithRootViewController:nxt];
nvc.modalPresentationStyle=UIModalPresentationFormSheet;
[self.preLCtr.preCinescape_iPadViewController presentModalViewController:nvc animated:YES];
I am not sure about the size of PesentationSheet. I tried to take screenshots & take dimentions/size. But its not the exact solution.
Question : What is the exact size of Present-Modal-Sheet in iPad ?
This is what I found for the current (iPad 3) iO6 dimensions:
BOUNDS: 540.000000, 620.000000 - Portrait-no-keyboard.
But you shouldn't use this for any code. Follow the correct answer.
According to Apple's documentation the size could change depending on the available screen size:
The width and height of the presented view are smaller than those of the screen and the view is centered on the screen. If the device is in a landscape orientation and the keyboard is visible, the position of the view is adjusted upward so that the view remains visible. All uncovered areas are dimmed to prevent the user from interacting with them.
Maybe in the viewcontroller that is loaded to the FormSheet you can determine the view size at runtime by using: self.view.bounds;
If you need to resize the FormSheet i saw some answers on stackoverflow
If you're adjusting a freeform view controller so that you can get the aspect right for a modal transition with form sheet presentation style, note that there is a Form Sheet option under the Size dropdown in the Size Inspector. I didn't notice this at first.
I checked different orientation and also in multi window mode, the default size is
width: 540, height: 620.
And below is the screenshot from Reveal.

UISearchDisplayController gray overlay not fully covering table

I'm having an issue where the gray overlay that's automatically put over my UISearchDisplayController when the keyboard is shown doesn't always fully cover the table area (you can see the white on the bottom in the picture below). This doesn't always happen but it's frequent enough that it's annoying. Anyone know what's going on? Thanks.
I believe this is a bug in Apple's code. Having worked extensively with UIPopoverControllers, I have found that there are many occasions in which a popover becomes confused as to whether or not it has a navigation bar when performing sizing calculations.
I am confident that if you measure the height of the white box you will find that it is exactly 37 pixels: the height of a navigation bar in a popover. (Navigation bars in popovers are not 44 pixels high like most navigation controllers since they are embedded into the popover's border.)
If you were able to access the gray overlay and manually resize it you could account for the height of the navigation bar or lack thereof. Unfortunately you are in a bit of a bind since the overlay is controlled by the search bar.
My suggestion would be to try to get the popover to recompute the size of its contents after it appears or is resized. I use this pattern when dynamically resizing a UIPopover containing a navigation bar when it appears:
// UIViewController subclass with a navigation bar which is displayed in a popover
// _popoverController is a (unretained) pointer to the UIPopoverController in which this view controller is displayed
- (void)viewDidLoad
{
[self.view sizeToFit];
CGSize newSize; // Dynamically computed based on popover contents
self.contentSizeForViewInPopover = newSize;
newSize.height += 37; // Account for popover navigation bar
[_popoverController setPopoverContentSize:size animated:YES];
}
I don't know how much this answer will help, but I hope it will at least give you a push in the right direction.
Have a look in this post: http://www.cannonade.net/blog.php?id=1498
He discusses the problem, providing a (called by himself) ugly workaround, but also says how to fix it!

How come some of my UIViews are shifted after navigation?

In some of my application designs or for just some UIViews, following a navigationController's pushViewController, my new view will be shifted off the window by the height of the status bar. As a result, I will put this code stub in the viewDidLoad method.
CGRect frameAt = [self.view frame];
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
frameAt.origin.y += statusBarFrame.size.height;
[self.view setFrame: frameAt];
It does not make sense to me that this is the intention of XCode and Interface Builder, so I suspect that I am doing something fundamentally wrong with the SDK during my view design. Furthermore, on the rare occasion that I don't have to shift my view, I really don't know what the difference in the two design approaches.
Note also, that most of the time I try to design my views using IB, with some minor customization.
Does anyone else run into this and know what they do to fix without such a code stub?
I've used Apple's NavBar sample code to try and reproduce this problem.
the applicationDidFinishLaunching is originally implemented like this:
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
If I change it to this:
UIViewController *shellController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
[shellController.view addSubview:navigationController.view];
[window addSubview:shellController.view];
[window makeKeyAndVisible];
Then I get the gap appearing.
However if I only do this:
UIView *shell = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[shell addSubview:navigationController.view];
[window addSubview:shell];
[window makeKeyAndVisible];
Then everything looks normal.
So I guess every view controller will offset its view if its the root view controller. But the navigation controller overrides this behaviour to offset its view regardless of whether it's the root view controller. Therefore I would say your gap is appearing because you've got a navigation controller somewhere lower in the hierarchy than it's supposed to be.
The main thing to keep in mind here is that a view controller will set the frame of its view itself. This is because the amount of space available to the view may change during the lifetime of the app, and only the view controller knows how to adjust the view's frame appropriately. Examples of when the amount of space changes include the navigation bar changing height, turning the device from portrait to landscape and the status bar can also increase in height if the user is taking a call. Because of this you should not modify the view's frame yourself.
So, the first thing you need to is is remove all code related to modifiying the view's frame.
Now you need to design your views with the mindset that the frame size could change at any moment. This means setting the autoresizing property of each subview properly. If you do this, then it won't matter if you turn on the simulated navigation and status bars or not; they're just there to help you see what the final result will look like in most cases.
You can set the autoresizing property of each subview in Interface Builder in the Size Inspector (the one with the ruler icon). In the animation, the white box represents the root view of the view controller, the red box represents the currently selected subview. You'll notice that the subview is anchored to the top-left corner of the root view by default. This is fine if the size of the view never changes, but we know that not to be true. If you have subviews that you want to appear at the bottom no-matter-what, then you need to play with the diagram to the left. The way it works is if one of the four lines around the edge is selected, then the distance between that edge of the root view and the edge of the subview is fixed. So if you want a subview to appear at the bottom, you need to make sure the bottom-most line is selected and not the top. The two lines in the middle affect whether the size of the subview changes when the root view change size. So, for example, if you had a table view that you wanted to occupy the entire height of the screen, you would make sure the inner vertical line was selected. This is called the struts and springs model.
If you are adding subviews programatically you need to set the autoresizingMask property on each subview. Here's an explanation.
Hope that helps!
I've run into similar issues. Check out my two previous questions:
IPhone - After dismissing Modal View Controller - gap is left at top of page
IPhone - UIView addSubview Gap at top
link text
A similar bug is discussed here.
Also is animation set to NO? Try setting it to YES as this solved a similar problem I was facing.
Moshy's answer was very helpful as I finally realized the meaning of the dotted/solid lines in IB for controlling the resize properties of UIView elements.
However, adjusting those properties did not address a similar problem I faced with one of my views. This view had a status and top bar defined in IB. It was a slightly heavy one,
containing a UIWebView that would load a HTML string within viewWillAppear and a few other interface elements.
While loading the view, if the user suddenly changed the orientation of the device from portrait to landscape, all contents of the view would shift downwards by the height of the status bar. The resulting gap between the view controls and its top would remain even after switching back to portrait orientation.
What finally solved my issues, and my remaining hair, was adding the line:
self.view.frame = [[UIScreen mainScreen] bounds];
within
-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
Ever since my view contents are held in place despite abrupt device orientation changes.

Resources