UIPopoverController Appears in Wrong Spot

Chris picture Chris · Jul 8, 2011 · Viewed 8.5k times · Source

So I've spent some time looking for an answer for this, but so far haven't found anything.

I'm trying to present a popover from a button on an UIInputAccessoryView. The UIBarButtonItem i want to display the popover from has a custom view so I can use an image. I create the button like this:

 buttonImage=[UIImage imageNamed:@"tags.png"];
 aButton=[UIButton buttonWithType:UIButtonTypeCustom];
 [aButton setImage:buttonImage forState:UIControlStateNormal];
 aButton.frame=CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
 UIBarButtonItem* compButton2=[[UIBarButtonItem alloc]initWithCustomView:aButton];
 [aButton addTarget:self action:@selector(tagIt:) forControlEvents:UIControlEventTouchUpInside];

When it comes time to display the popover, I do it like this:

CGRect tRect=[((UIButton*)sender) convertRect:((UIButton*)sender).frame toView:self.notePlainText];
NSLog(@"TagIt tRect: %f %f %f %f", tRect.origin.x, tRect.origin.y, tRect.size.width, tRect.size.height);
[self.popoverController presentPopoverFromRect:tRect inView:self.notePlainText permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

But what I get is this:

enter image description here

The popover looks fine, but it appears over the second button when it should be appearing over the first.

So then I found this question: UIBarButtonItem with custom image and no border and I thought, "ah, perhaps it will work better if I present the popover from a barbuttonitem instead of doing it this way. The code sub classes UIBarButtonItem in order to have a button with an image, not text, and represents the barbuttonitem properly when the action is called. This allowed me to use ...presentPopoverFromBarButtonItem...

So I tried the code in the second answer in the aforementioned question, and got a result that was better. The popover points right to the button as I wanted, but if the orientation of the device is not portrait with the button on the bottom, the popover displays with the wrong orientation:

Popover with wrong orientation

Finally, I will point out that I have other bar button items elsewhere in the program that are not in UIInputAccessoryViews that come up properly and without issue. It only seems to be happening form the input accessory view.

This just in: Hiding and showing the keyboard seems to make this work a bit better. Looking at the frame (CGRect) data for the button, it doesn't change between rotations unless it's hidden and brought back. Is this a bug?

So.. my question is this: what is the preferred, best-practices way of presenting a popover from a bar button item embedded in a ui accessory view?

Thank you very much.

Answer

Chris picture Chris · Jul 9, 2011

So I got this to work with the following kludgy code, although if someone could tell me why I have to do this (or why I SHOULDNT do this) I would be much obliged.

CGRect r=((UIButton*)sender).frame;
CGRect tRect=[((UIButton*)sender) convertRect:((UIButton*)sender).frame toView:self.view];
tRect.origin.x=r.origin.x;

[self.popoverController presentPopoverFromRect:tRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];