UIAlertController not working - ios

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Initialize Alert View
let alertController = UIAlertController(title: "No Internet connection", message: "Please Connect to Internet", preferredStyle: .Alert)
let EXITAction = UIAlertAction(title: "EXIT", style: .Destructive) {(action) in
//...
exit(0)
}
alertController.addAction(EXITAction)
self.presentViewController(alertController, animated: true) {
// ...
}
}
I'm trying to use this for onLoad if use click then exit.
but nothing happen. Please help
(I am quite new in programming)

You have to move your code to present the UIAlertController to the viewDidAppear method.
If you put code that modifies the user interface in the viewDidLoad, it won't be applied to the views because the view controller is still loading.

Just declare a function like follows and you can call it in your viewDidAppear() method as alert("Message String").
func alert(info:String) {
let popUp = UIAlertController(title: "Title", message: info, preferredStyle: UIAlertControllerStyle.Alert)
popUp.addAction(UIAlertAction(title: "OK!", style: UIAlertActionStyle.Default, handler: {alertAction in
popUp.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(popUp, animated: true, completion: nil)
}

Related

UIAlertAction closure is not being called when presenting Controller is modal

I have a UIViewController which is embedeed in UINavigationController which is being presented modally over my application's keyWindow.rootViewController. When I present UIAlertController in any screen of the presented navigation controller, the alert controller is correctly displayed but the closures for any of the UIAlertAction are not being called after being pressed.
I am displaying the same alert controller with the same code in view controllers belonging to the main navigation controller of my app and the closures are called properly.
The code for presenting the alert is very simple, here's the snippet:
// Creating Alert
func createAlert() -> UIAlertController {
let actions: [UIAlertAction] = [
UIAlertAction(title: "Something", style: .default, handler: { _ in
self.setOriginalQueue(with: items, description: description, identifier: identifier)
self.setQueue()
}),
UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in
normal()
})
]
let alert = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet, actions: actions)
return alert
}
// In ViewController
DispatchQueue.main.async {
self.present(alert, animated: true, completion: nil)
}
So the question is, why are the closures not being called?
UIAlertController does not contain four types argument. See the document.
Once you fixed that, the rest will be automatically fixed like below.
For everyone's convenience I'll put the whole Modal view controller class source here.
class ModalViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.present(createAlert(), animated: true, completion: nil)
}
func createAlert() -> UIAlertController {
let actions: [UIAlertAction] = [
UIAlertAction(title: "Something", style: .default, handler: { _ in
print("Something")
}),
UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in
print("Cancel")
})
]
let alert = UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet)
for action in actions {
alert.addAction(action)
}
return alert
}
}
The line is wrong.
let alert = UIAlertController(title: nil, message: "message" , preferredStyle: .actionSheet, actions: actions)
You must be get error like that
Type of expression is ambiguous without more context
Change it like that:
return UIAlertController(title: YourTitle, message: YourMessage, preferredStyle: UIAlertController.Style.actionSheet)
So it can work.
Need to pass name of the method when you are presenting alert
self.present(createAlert(), animated: true, completion: nil)

Displaying a UIAlert before dismissing the view

My view is being dismissed through the previous button on the navigation bar. I think the correct term for that is that the view is being popped off the view stack. Now before actually dismissing the view I want to display a UIAlert asking the user to setup his/her address.
I've tried this but the UIAlert is not being show:
override func viewWillDisappear(animated: Bool) {
if let currentUser = ApiManager.sharedInstance.currentUser {
if !currentUser.hasAddress {
let alert = UIAlertController(title: "Missing address", message: "We see you're stilling missing an address, would you like set it now?", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "yes".localized, style: .Default, handler: { (alertAction) in
let newViewController = LocationViewController()
newViewController.delegate = self
self.navigationController?.pushViewController(newViewController, animated: true)
}))
alert.addAction(UIAlertAction(title: "no".localized, style: .Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
}
In my console the following gets printed:
2016-10-28 16:58:47.380 gaifong[17096:14515422] Warning: Attempt to present <UIAlertController: 0x7fd7037e4cb0> on <gaifong.ProfileViewController: 0x7fd7048cc000> whose view is not in the window hierarchy!
You should add leftBarButtonItem on navigationItem and make an action to leftBarButtonItem where you can handle this.
in viewDidLoad
self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.Plain, target: self, action: #selector(self.goBack))
// Then handle the button selection
func goBack() {
if let currentUser = ApiManager.sharedInstance.currentUser {
if !currentUser.hasAddress {
let alert = UIAlertController(title: "Missing address", message: "We see you're stilling missing an address, would you like set it now?", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "yes".localized, style: .Default, handler: { (alertAction) in
// here you can pop to main controller
self.navigationController?.popViewControllerAnimated(true)
}))
alert.addAction(UIAlertAction(title: "no".localized, style: .Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
}

Displaying an alert on a new View Controller

I have a button that sends me on another View Controller. What I am trying is to display an alert on the next View Controller.
In the viewDidLoad() method of the new controller, create a new UIAlertController and display it like the following
let alertController = UIAlertController(title: "Default Style", message: "A standard alert.", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
// ...
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true) {
// ...
}
Note that this example was taken from the NSHipster website which offers nice articles about iOS. You can find the article about UIAlertController here. They also explain other stuff you can do with that class, like display an Action Sheet for example.
Swift 4
Create an extension of UIViewController with your function to display alert with required parameter arguments
extension UIViewController {
func displayalert(title:String, message:String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction((UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
alert.dismiss(animated: true, completion: nil)
})))
self.present(alert, animated: true, completion: nil)
}
}
Now call this function from your view controller:
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.displayalert(title: <String>, message: <String>)
}
}

UIAlertController Keeps Re-Appearing After Closing It

I have written code for an alert to appear when the input in one of my UITextFields is less than 1050. It successfully appears when the inputs satisfies that, but after I press "OK" it instantly re-appears.
Below is the code in the viewDidLoad function:
override func viewDidLoad(){
super.viewDidLoad()
alert = UIAlertController(title: "Error", message: "Please enter an exit width value greater than 1050", preferredStyle: UIAlertControllerStyle.Alert)
let okay = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler: valueCalc)
alert.addAction(okay)
}
Then I have in my valueCalc function (which is called when a button is tapped):
#IBAction func valueCalc(sender: AnyObject){
if(Int(mmText.text!)! < 1050){ //mmText is an UITextField
self.presentViewController(alert, animated: true, completion: nil)
}
}
According to your line of code
let okay = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler: valueCalc)
Your handler name valueCalc is called when you press OK.
Again the value is calculated which when come out be less then the specified characters shows back you the alert.
Instead of that, replace this line in your code -
let okay = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler: handlerMethod)
and add this method to your code
func handlerMethod() {
//handle your action here after ok is pressed for e.g if you wanna just dismiss the alert then write
dismissViewControllerAnimated(true, completion: nil)
}
You have the handler argument for your UIAlertAction set to valueCalc. Therefore, whenever the user taps "OK", the method valueCalc gets run again, and since the value is (presumably) still the same, the alert is presented right back again.
Try this
override func viewDidLoad(){
super.viewDidLoad()
alert = UIAlertController(title: "Error", message: "Please enter an exit width value greater than 1050", preferredStyle: UIAlertControllerStyle.Alert)
let okay = UIAlertAction(
title: "OK",
style: UIAlertActionStyle.Destructive) { (action) in }
}
#IBAction func valueCalc(sender: AnyObject){
if(Int(mmText.text!)! < 1050){ //mmText is an UITextField
self.presentViewController(alert, animated: true, completion: nil)
}

ELCImagePickerController delegate methods not called

I'm trying to build an app using ELCImagePickerController. I found that I could select multiple pictures. However, the ELCImagePickerController delegate method was not called.
This is my code:
#IBAction func uploadImages(sender: AnyObject) {
// Create the alert controller
//var alertController = UIAlertController(title: "", message: "", preferredStyle: .Alert)
var alertController = UIAlertController(title: nil, message: nil, preferredStyle: .Alert)
// Create the actions
var takeAction = UIAlertAction(title: "Take Photos", style: UIAlertActionStyle.Default) {
UIAlertAction in
NSLog("Take Photos Pressed")
}
var selectAction = UIAlertAction(title: "Select Photos", style: UIAlertActionStyle.Default) {
UIAlertAction in
NSLog("Select photos Pressed")
var imagePicker = ELCImagePickerController(imagePicker: ())
imagePicker.maximumImagesCount = 2
imagePicker.returnsOriginalImage = false
imagePicker.returnsImage = true
imagePicker.onOrder = true
imagePicker.delegate = self
self.presentViewController(imagePicker, animated: true, completion: nil)
}
var cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
}
// Add the actions
alertController.addAction(takeAction)
alertController.addAction(selectAction)
alertController.addAction(cancelAction)
// Present the controller
self.presentViewController(alertController, animated: true, completion: nil)
}
}
func elcImagePickerController(picker: ELCImagePickerController!, didFinishPickingMediaWithInfo info:[AnyObject]!) {
NSLog("controller executed.")
}
You need to set the ImagePicker delegate
imagePicker.imagePickerDelegate = self
Are your NSLog statements ever getting called? One thing I notice in your trailing closure syntax is that you're using the type name versus a variable of that type. For instance, you're writing UIAlertAction in ... vs alertAction in .... You should be providing a name to be used within the closure rather than the type itself. If the rest of the closure is not executing, then the delegate is never being set, and therefore delegate methods are never called.

Resources