Reputation: 916
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
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 {
//
}
}
Upvotes: 2
Views: 395
Reputation: 1120
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
Upvotes: 2