2

Popover location from my tap (Swift)

How can I make it so that when I click on the link then the popover would appear next to the click as shown in the picture?


I tried to add it but then it is displayed in the upper left corner

optionMenu.popoverPresentationController?.sourceView = self.view

enter image description here

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
    if (URL.scheme?.contains("mailto"))! {
        let optionMenu = UIAlertController(title: nil, message: "\(URL)", preferredStyle: .actionSheet)
        // 2
        let NewAction = UIAlertAction(title: "New Mail Message", style: .default, handler: { (alert: UIAlertAction!) -> Void in
            print("New Mail Message")
            UIApplication.shared.open(URL)
        })
        //
        let CopyAction = UIAlertAction(title: "Copy", style: .default, handler: { (alert: UIAlertAction!) -> Void in
            print("Copy Email")
            UIPasteboard.general.string = "\(URL)"
        })
        //
        let CancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: { (alert: UIAlertAction!) -> Void in
            print("Cancelled")
        })
        // 4
        optionMenu.addAction(NewAction)
        optionMenu.addAction(CopyAction)
        optionMenu.addAction(CancelAction)
        // 5
        self.present(optionMenu, animated: true) {
            print("Email menu presented")
        }
    } else {
    //
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
B2Fq
  • 876
  • 1
  • 8
  • 23
  • 1
    That you get an idea, the sourceView should be the "view" you clicked on. For example if you have a button and the popover should appear next to it, the source view should be the button. Also, you can define the rect where the popover should anchor with popoverPresentationController?.sourceRect = CGRect(x: 0, y: 0, width: yourView.frame.size.width, height: yourView.frame.size.height). What you need to find out is, how to get the marked text as a view to position your popover. Maybe you can add a transparent view on the touch location or something like this. – Retterdesdialogs Jan 03 '18 at 16:31

1 Answers1

2

You almost got the job done. What you need is to detect where the link is located on the screen and present the alert there.

Pre setup for the presentationController:

//You may also consider allowing UIPopoverArrowDirection.up.down if it suits your case.
optionMenu.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.up
optionMenu.popoverPresentationController?.sourceView = textView

How to locate where the link is:

guard let beginning = textView.position(from: textView.beginningOfDocument, offset: characterRange.location),
        let end = textView.position(from: textView.beginningOfDocument, offset: characterRange.location + characterRange.length),
        let textRange = textView.textRange(from: beginning, to: end) else {
            //Cannot locate link
            return false
    }

//move the presentationController to point to the link
optionMenu.popoverPresentationController?.sourceRect = textView.firstRect(for: textRange)

If you are interested in what kind of magic that is, you can read more here

dvp.petrov
  • 1,110
  • 13
  • 20