UIPopoverController: Why my popover doesn't appears where i want to? - iphone

Simple:
A view, i present a UIPopoverController in a CGRect using presentPopoverFromRect...
and neither the arrow or the popover frame appear even near to the coordinates i asked for in the rect i passed into.
Any clues?
I've been trying to figure out this by myself but am giving up. Here is the code:
if(!myContentController){
myContentController = [[MyContentController alloc] initWithNibName:myNibName bundle:[NSBundle mainBundle]];
// This works pretty well. actually when i show the popover
// i see everything inside as it's supposed to.
}
if(!popover){
popover = [[UIPopoverController alloc] initWithContentViewController:myContentController];
}
else{
[popover setContentController:myContentController];
}
popover.delegate = self;
CGPoint touchPointInView = [self touchPoint];//This is working fine too.I've been checking with NSLog.
popover.ContentSize = myPopoverSize;//In this case {320,480}
[popover presentPopoverFromRect:CGRectMake(touchPoint.x,touchPoint.y,myPopoverSize.width,myPopverSize.height)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
What happens next? the popover doesn't shows where it should be. If i pass {0,0} it shows in the middle of the screen as if the view size were (768,512). I checked all the view dimensions and they are all ok, frame,bounds, etc... . Does anyone knows what am i doing wrong?

The CGRect you give to presentPopoverFromRect is the rect that it will display the popover next to (not in). Depending on the location of the rect, the popover will appear on an appropriate side of the specified rect.
If you want the popover to appear at a specific point, give it a rect with the origin as the point and the size as 1,1. So the CGRectMake in the presentPopoverFromRect line should be:
CGRectMake(touchPoint.x,touchPoint.y,1,1)
Also make sure that the touchPoint is relative to the inView (self.view in your case).
By the way, there are a few other errors in the code (probably just typos in the question):
setContentController should be setContentViewController
popover.ContentSize should be popover.popoverContentSize
myPopverSize.height should be myPopoverSize.height (but this will be replaced by 1)

In my case the reason of this problem was following. It is also possible, that your view is a tableView. So, when you scroll it and try to show UIPopover in a rect in that tableView, it may not be shown. I used this:
[_popoverController presentPopoverFromBarButtonItem:self.navigationItem.rightBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

Related

presentPopoverFromRect from a button goes out of bounds

So I am using WEPopover to display a custom view controller pop up. I have a UIView in which inside it has another UIView called containerView. Inside this containerView, I have a UIButton. This is where I wanted to present my popover from. So here's what I did:
[self.popoverDialog presentPopoverFromRect:sender.frame inView:self.containerView permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
The issue is that the arrow and everything is showing from this button, but the popover goes out of self.containerView bounds. How can I make it so that the popover is displayed within the containerView bounds?
EDIT:
A picture is worth a thousand words, so here it is:
The light gray is the containerView I mentioned above. THe popover theoretically should be shown within that light gray bounds not going outside.
For the view that is contained inside the popover, go to it's view controller and set it's property contentSizeForViewInPopover. Here you can set the size so that it fits the bounds of your containerView.
OP wants to position the popover so that it only shows up in his container view. I found this bit of code in the WEPopoverController.m file
- (void)repositionPopoverFromRect:(CGRect)rect
inView:(UIView *)theView
permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections {
CGRect displayArea = [self displayAreaForView:theView];
WEPopoverContainerView *containerView = (WEPopoverContainerView *)self.view;
[containerView updatePositionWithAnchorRect:rect
displayArea:displayArea
permittedArrowDirections:arrowDirections];
popoverArrowDirection = containerView.arrowDirection;
containerView.frame = [theView convertRect:containerView.frame toView:backgroundView];
}
You could possibly call this method and it might reposition your popover so that it is now inside your container viw.

PopOver Open in Leftside up+iphone

I want to open a popover on button click event.
Like below image:
But what i m getting is:
The Code i had used for the popover is:
PopOver *PopOver_obj=[[PopOver alloc]initWithNibName:#"PopOver_ipad" bundle:nil ];
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:PopOver_obj];
popoverController.delegate = self;
CGSize maximumLabelSize = CGSizeMake(320.0f,200.0f);
popoverController.popoverContentSize = maximumLabelSize;
CGRect rect = CGRectMake(100,100, 200.0f, 100.0f);
[popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
UPDATE
For iOS 5 you can use popoverLayoutMargins property of the popover to set an inset relative to the device's screen edges. See this for more detail.
As far as I can see from your screenshot you have a black colored view and a white one but you are showing the popup in their superview.
You can try using - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated method and pass the white view as the view argument of the method and UIPopoverArrowDirectionUp for the arrowDirections argument.
I think that might restrict the popover to go outside the view thus keeping it under your + button.
Let me know if that helps.

Views inside views (iOS, Drawing properties)

Ok, I recognize that I have a complete mess in my mind.
Really, the objective is very simple. I have a little subview inside one of my views (I've added it in Interface Builder). I'm trying to insert inside a little subview that automatically resizes herself to occupy the exact space of his parent view.
Controller *c = [[Controller alloc] initWithNibName:nil bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:c];
[self.containerView addSubview:self.navigationController.view];
[c release];
Controller class contains an UIImageView pretty big. But I've set the properties of the view and the image to 'scale to fill' and size itself properly. However, the image automatically exceeds the area of the view showing bigger and occupying all the window.
Ideas? Thanks a lot!
Additional:
After applying meggar's method I have an strange behaviour. The container view is in position 277,176 with a dimensions of 214w,204h. The inserted view is appearing with the same dimensions but translated 100px (aprox.) to the right.
What kind of effect can be causing it?
setting the view's frame equal to its superview's frame should do the trick, something like:
UIView* parentView = self.navigationController.view.superview;
CGRect myFrame = CGRectMake(0,0,parentView.frame.size.width,parentView.frame.size.height);
[self.navigationController.view setFrame:parentView.myFrame ];
[self.containerView addSubview:self.navigationController.view];

get frame of UITextField in UITableView for displaying UIPopover

I need to present a UIPopover from dynamically generated UITextFields in a UITableView. They are all tagged uniquely but when I try and use this code the popover just show up in the upper left hand corner:
[self.numbersPopover presentPopoverFromRect:[self.childSkusTable viewWithTag:aTag].frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
EDIT:
I see I am finding the frame for that tagged item but it is relavant to it's parent cell, in this case the frame of that tagged items is 0,0 for the x,y. How do I get it's position in the main window view?
Answering this just incase someone else needs it.
You have to get you UiTextFields position in the UIWindow like so:
UIView *v = [self.view viewWithTag:aTag];
CGPoint pos = [v.superview convertPoint:v.frame.origin toView:nil];
Then I just did this:
[self.numbersPopover presentPopoverFromRect:CGRectMake(pos.x, pos.y, 35, 10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
The finding positioning code form above came from this questions and answer: iPhone - Get Position of UIView within entire UIWindow

iOS -- how do you control the size of a modal view controller?

I am presenting a modal view controller. If it matters, it is scrolling up from the bottom. How can I control what portion of the screen it occupies?
EDIT: I have the following in the modal view controller. It's not helping.
- (void)viewDidLoad {
TestResultView *trv = [[TestResultView alloc]initWithTest: [Model m].currentTest];
self.view = trv;
trv.frame = CGRectMake(0, 320, 320, 160);
[trv release];
[super viewDidLoad];
}
You can modify the frame of the view controller, but if you're using UIViewController's -presentModalViewController:animated: method, the view behind will be unloaded once your modal view is finished animating onto the screen (This assumes you're on an iPhone) and you'll see a white screen where your background view should be. iOS assumes that your modal view controller will be a full-screen view controller, and dumps the other view to save memory.
If you really want to show a view over part of the screen, you should instead add the UIView (no UIViewController) to your current UIViewController's view as a subview, and then animate it onscreen yourself. I think something like this would work in your UIViewController class that will present the view:
// Add the view as a subview and position it offscreen just below the current view
UIView *myHalfView = [[UIView alloc] initWithFrame:someAppropriateFrame];
[self.view addSubview:myHalfView];
CGRect offScreenFrame = myHalfView.bounds;
offScreenFrame.origin = CGPointMake(0.0, CGRectGetMaxY(self.view.frame));
// Now animate the view upwards
[UIView beginAnimations:nil context:nil];
// Move the view upwards the height of your sliding view so it's entirely onscreen
myHalfView.center = CGPointMake(myHalfView.center.x, myHalfView.center.y - myHalfView.bounds.size.height);
[UIView commitAnimations];
[myHalfView release];
For bonus points, you could fade the view in by setting
myHalfView.alpha = 0.0;
before the UIView animation block, and setting
myHalfView.alpha = 1.0;
inside the block after animating the center property.
When you're done, you can do something similar but in reverse to slide the view offscreen. You can add an animationDidStop selector to the UIView animation block to be notified when the view has slid off screen so that you can remove it from the view hierarchy.
From an aesthetic point of view, you should also be careful how you do this since having a view slide up is a standard behavior, and if your view looks like a normal view but stops halfway, users may feel (even briefly) that the app has frozen. They'll figure it out, but it will leave a bad feeling about your app if not handled carefully. Mainly, I would avoid using standard full-screen cues like including a UINavigationController at the top of your view to help users understand what's going on. Half-sheets tend to be UIActionSheets on the iPhone, so think in that direction.
That is nice, the above accepted answer explains a nice hack to present subViews which feel like ModalViews, but what if it is an iPad, and i can indeed give it a modalViewController which doesnt cover the entire screen.
In case of iPads, I dont think the underneath view will be unloaded. ( because there are options where we can present the modalView on iPads, which dont cover the entire screen )
ModalViewController in the end is a controller itself, and like any other controller has a root view, whose properties can be editted, if we can get hold of it.
Here is what will give you a custom frame of the ModalView :
MyViewController *viewController = [[MyViewController alloc] init];
viewConroller.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:viewController animated:YES];
//superView of viewController's view is modalViewController's view, which we were after
viewController.view.superview.frame = CGRectMake(x,y,w,h);
//x y w h - can have desired values.
I would add to #dsaw's answer that the superview of the modal view does not seem to rotate its coordinate system in landscape mode. Here is the code that I used in my own app:
MyViewController* modalVC = [[MyViewController alloc] init];
modalVC.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:modalVC animated:NO];
CGRect r = CGRectMake(self.view.bounds.size.width/2 - 236,
self.view.bounds.size.height/2 - 130,
472, 260);
r = [self.view convertRect:r toView:modalVC.view.superview.superview];
modalVC.view.superview.frame = r;
While the superview may not rotate itself with the iPad, it does seem to do the right thing and keep the modal view centered if I rotate the iPad after showing the modal view.