I have a text view inside a table view cell that can contain URLs. When the user taps on the URL, I want to present an alert to ensure the user wants to continue before handling the URL. I'm trying to implement this within the proper delegate method, but I'm stuck because the return value can't be in the completion block of the alert. How can I wait for the user to make a choice before returning from this method?
Relevant code:
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
var alert = UIAlertController(title: "Are you sure?", message: "You are about to leave the app to open an external link", preferredStyle: .alert)
let yesAction = UIAlertAction(title: "Yes", style: .default) { _ in
alert.dismiss(animated: true) {
// return true would go here
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in
alert.dismiss(animated: true) {
// return false would go here
}
}
alert.addAction(cancelAction)
alert.addAction(yesAction)
UIApplication.shared.firstKeyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
// Traditionally the return should go here
}
It's bad practice to make delegates wait for a response. My work around to the solution was
alert.dismiss(animated: true) {
UIApplication.shared.open(url)
}
and returning false to the delegate. That way I leave the URL handling to my code rather than to iOS native behavior