UIAlertController dismiss completion never gets called - swift

In the following code, when my web view fails to load, the alert is properly shown with the Retry button, as expected. The alert goes away when tapping the Retry button, but the completion never gets called. Why is this?
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
let alert = UIAlertController(title: "Network Error", message: "There was a error loading the page.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Retry", style: .default, handler: { _ in
alert.dismiss(animated: true, completion: {
self.webView.loadHTMLString("Reloaded", baseURL: nil)
})
}));
self.present(alert, animated: true, completion: nil)
}

Don't call alert.dismiss inside the alert action. The alert controller will automatically be dismissed when the user taps one of the alert buttons.
You just need:
alert.addAction(UIAlertAction(title: "Retry", style: .default, handler: { _ in
self.webView.loadHTMLString("Reloaded", baseURL: nil)
}))

Just try it out I didn't checked ,
Change UIAlertActionStyle .default to .Cancel. Remove dismiss block give web view loading directly in handler..
Hope maybe it will help you...

Related

UIAlertController is complete and presented but does not appear during viewDidLoad

I have this alert controller setup to appear as soon as the view controller is loaded. However, it does not appear.
I believe I have all the facets covered - title, message, alert style, action button and present... but still does not appear.
Unsure what I'm missing.
let array = quoteBank()
print(array.sarcasticQuotes[0].quote)
let title = "Message"
let message = array.sarcasticQuotes[0].quote
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(.init(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
Attempting to show an alert in viewDidLoad is too soon. The view controller isn't displayed yet. Use viewDidAppear.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Use this if statement to only show the alert once
if self.isBeingPresented || self.isMovingToParentViewController {
// show your alert here
}
}
You need to perform that on the main thread:
DispatchQueue.main.async {
present(alert, animated: true, completion: nil)
}
The reason behind that is that the view controller's hierarchy will be set after viewDidLoad is finished. So by doing this, you're scheduling the presentation of the alert on the main thread to the time the main thread is finished from executing viewDidLoad.

UIAlertController Showing With Delay

I am having a lot of delay with my UIAlert, whenever it loads I have to wait before I can click and then again for it to fully disappear. I have looked at other answers that recommended using dispatch_async(dispatch_get_main_queue(), {}). I have tried using this but to no avail. The alert pops up during the render loop for a scene kit game I am making (the scene is just a cube and when I pause the scene it is still delayed). Shouldn't rendering be done in the render thread anyway. I looked the through the time profile log to see if something was blocking the Main Thread but I did not see anything that caught my attention (I fairly new to the instruments).
Here is my code where I am creating the alert:
func share(){
print("share funciton")
let alert = UIAlertController(title: "Share", message: "Where do you want to share?", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Twitter", style: .Default, handler: {(alert: UIAlertAction!) in
print("twitter")
self.showTwitter()
}))
self.presentViewController(alert, animated: false, completion: nil)
}
private func showTwitter() {
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter) {
let tweetShare:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
self.presentViewController(tweetShare, animated: true, completion: nil)
} else {
let alert = UIAlertController(title: "Accounts", message: "Please login to a Twitter account to tweet.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
Then I call share() when in the render loop with a dispatch_asych. I've been working at this bug for three days but have no idea what's causing the delay.
Try turning slow animations off. Open simulator -> debug -> slow animations

How To Make an Alert Only Appear Once

I'm trying to figure out is how to create a pop up window that only appears once when you start the app and then won't appear again unless you close the app and reboot it. However, if you view the code below, you will realize that the alert will pop up every time the ViewController appears. For example, if you go to the settings tab and then return to the main ViewController, then the alert will pop up.
override func viewDidAppear(animated: Bool) {
let alertController = UIAlertController(title: "Disclaimer", message: "WARNING: Please ride carefully!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Accept", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
Just create a global variable that is a Bool. If the app is opened it starts at false. Then once the disclaimer is seen it sets the variable to true. Then present the View Controller based on the value of the variable.
var disclaimerHasBeenDisplayed = false
class ViewController {
override func viewDidAppear(animated: Bool) {
if disclaimerHasBeenDisplayed == false {
disclaimerHasBeenDisplayed = true
let alertController = UIAlertController(title: "Disclaimer", message: "WARNING: Wakeboarding is fun, however it can be highly dangerous.
Wake Dice is not liable for any injuries obtained while wakeboarding. Please ride carefully!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Accept", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
}
}

How do i make this UIAlert appear

I am trying to make an alert by pressing a button "delete data". My button is in a view which is inside a navigation controller. Here is my current code
class SomeViewController: UIViewController {
#IBAction func deleteData(sender: UIButton) {
let alert = UIAlertController(title: "delete Data", message: "Do you want to delete the data", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.Default, handler: nil))
}
}
But is gives me the following error:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior
You've created your alert view controller but you still need to present it:
self.presentViewController(alert, animated: true, completion: nil)
You can read an article on the topic on appcoda.com
for showing alert use:
self.presentViewController(myAlert, animated: true, completion: nil)
and for dismiss use:
alert.dismissViewControllerAnimated(true, completion:nil)

Show alert view when tap on phone number in web view with Swift

I'm having a web view that displays a company's address and phone number and email. The current behavior is when the phone number is tapped it is then dialled immediately.
Is there a way for me to prompt an alert view to let user confirm the call? Instead of calling it immediately?
Here is the function I use to initialize an alert:
func displayAlert(title: String, message: String) {
var alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { (ACTION) -> Void in
// self.dismissViewControllerAnimated(true, completion: nil)
alert.hidesBottomBarWhenPushed = true
}))
print("running Activityindicator code")
self.presentViewController(alert, animated: true, completion: nil)
}
and I call it like so:
self.displayAlert("Alert title", message: "alert message")
hope this helps!