R. Dewi
R. Dewi

Reputation: 4271

Set UIPopover arrow direction and position manually

I'm using UIBarButtonItem. In my scenario I want to show a popover from every bar button when I double-click that bar button. So I use a UITapGesture from that UIBarButtonItem. But, the popover arrow always appear in the middle of all UIBarButtonItem.

I can't make the arrow appear in the middle of each bar button. My friend was telling me to set the arrow direction using point, but I don't know how to do that.

How can I set both the position and direction of the popover's arrow?

Upvotes: 14

Views: 25149

Answers (5)

manoranjan nayak
manoranjan nayak

Reputation: 51

class MyViewController: UIViewController, UIPopoverPresentationControllerDelegate {

    @objc func expandClicked(sender: UIButton!) {
        let vc = UIViewController()
        vc.view.backgroundColor = .white
        display(viewcontroller: vc, size: CGSize(width: 150, height: 40), sender: sender)
    }

    func display(viewcontroller: UIViewController, size: CGSize, sender: UIView) {
        let controller = viewcontroller
        controller.modalPresentationStyle = .popover
        controller.popoverPresentationController?.delegate = self
        controller.preferredContentSize = size
        let presentationController = controller.popoverPresentationController!
        presentationController.sourceView = sender
        presentationController.sourceRect = sender.bounds
        presentationController.backgroundColor = .white
        let buttonPosition = CGPoint(x: sender.bounds.minX, y: sender.bounds.maxY)
        let p = sender.convert(buttonPosition, to: transactionTableView)
        if (transactionTableView.bounds.maxY - p.y) > 70 {
            presentationController.permittedArrowDirections = .up
        } else {
            presentationController.permittedArrowDirections = .down
        }
        self.present(controller, animated: true)
   }

   public func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
       return UIModalPresentationStyle.none 
   }
}

Upvotes: 2

Sam Ritchie
Sam Ritchie

Reputation: 11038

Set the direction for the popover using:

[yourPopover setPopoverArrowDirection: UIPopoverArrowDirectionDown];

You can also use UIPopoverArrowDirectionUp, UIPopoverArrowDirectionLeft, and UIPopoverArrowDirectionRight, and UIPopoverArrowDirectionAny.

For Swift

yourPopover?.permittedArrowDirections = .up // or .down, .left, .right

Upvotes: 23

Linh Dao
Linh Dao

Reputation: 1663

You can set the direction of the arrow in Storyboard Segue's attribute inspector. For example, I set the arrow direction to down only in the following screenshot: enter image description here

Upvotes: 0

Evgeny Karev
Evgeny Karev

Reputation: 613

I use method permittedArrowDirections = .Down, It's work for me. Swift example:

if let popoverPresentationController = shareViewController.popoverPresentationController {
    popoverPresentationController.permittedArrowDirections = .Down
    popoverPresentationController.delegate = self
    popoverPresentationController.sourceView = sender as! UIButton
    popoverPresentationController.sourceRect = CGRectMake(0, 0, sender.frame.size.width, sender.frame.size.height)
}

Upvotes: 15

Maple
Maple

Reputation: 741

If you are using an IBAction method, you can use (id)sender as its parameter. (i.e. the calling button) Then you can set the popover's attachment rectangle to the frame of the button. The arrow will do its best to attach along the side of this frame in an appropriate spot. See UIPopoverController Class Reference.

-(IBAction)sortButtonPressed:(id)sender {
  // Set up your popover class, this varies per your implementation
  MyPopoverClass *iPop = [[MyPopoverClass alloc] initWithNibName:@"MyPopover" bundle:nil];
  UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:iPop];

  // Grab the button info from the input parameter
  UIButton *button = (UIButton *)sender;
  CGRect buttonRectangle = button.frame;

  // Set the arrow direction
  UIPopoverDirection dir = UIPopoverArrowDirectionAny; // Or Up, Down, etc.

  // Put it all together
  [popover presentPopoverFromRect:buttonRectangle inView:mySubView permittedArrowDirections:dir animated:YES];

  [popover release]
  [iPop release];
}

You can also hardcode that CGRect by hand if necessary. Shrinking the width/height of the rectangle will allow you to more tightly control the arrow's position.

Upvotes: 0

Related Questions