UIPopoverController appears in the wrong place

So, I spent some time searching for an answer, but so far have not found anything.

I am trying to present a popover from a button on a UIInputAccessoryView. The UIBarButtonItem with which I want to display a popover has a custom look, so I can use an image. I create a button as follows:

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 the time comes to display a 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 I get the following:

enter image description here

Popsor looks great, but it appears above the second button when it should appear above the first.

So, I found this question: UIBarButtonItem with a custom image and without borders , and I thought: “Ah, it might work better if I present a popover from barbuttonitem instead of doing it this way. Subclass UIBarButtonItem classes in order to to have a button with an image, not text, and represents the barbuttonitem correctly when the action is called.This allowed me to use ... presentPopoverFromBarButtonItem ...

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

Popover with wrong orientation

Finally, I will point out that I have other elements of the bar panel elsewhere in the program that are not in UIInputAccessoryViews that appear correctly and without problems. It looks like this comes from the look of input accessories.

It's simple: Hiding and showing the keyboard seems to make this work a little better. Considering the frame data (CGRect) for a button, it does not change between rotations unless it is hidden and returned. This is mistake?

So my question is this: what is the preferred, best way to present a popover from a button element on a panel embedded in an ui accessory?

Many thanks.

+7
source share
6 answers

So, I got this to work with the following kludgy code, although if someone can tell me why I should do this (or why I do this), I would be very 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]; 
+8
source

I had exactly the same problem when popover was pointing to a different place in iOS 7 and thanks to Chris's answer . Finally, I was able to see the consistency between iOS 6 and iOS 7. I had to make 1 small adjustment to the code, replacing the frame with bounds so that it sits where I expected it to be.

 CGRect r = [sender frame]; CGRect tRect = [sender convertRect:sender.bounds toView:self.view]; tRect.origin.x=r.origin.x; [self.popoverController presentPopoverFromRect:tRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:NO]; 
+5
source

Use presentPopoverFromBarButtonItem:permittedArrowDirections:animated . To do this, make sure you have a link to your panel button (either by storing it in a property on the view controller, or using IBOutlet), and then call the popover method that you want to show.

+1
source

I used the same workaround in this answer ; this seems to be a problem with iOS 4.3 (maybe 4.x). It seems to be fixed in iOS 5.

+1
source

Try the following:

 [self.popoverController presentPopoverFromRect:[sender bounds] inView:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
0
source

You can simply compensate for this point:

 if segue.identifier == "layersPopover" { let vc = segue.destinationViewController let controller = vc.popoverPresentationController if controller != nil { controller?.delegate = self var rect = controller?.sourceRect rect?.offsetInPlace(dx: 19, dy: 0) controller?.sourceRect = rect! } } 
0
source

All Articles