How to create extension for UIAlertController in swift? - swift

I am trying to modulraise my code I am able to create extension for alertController without target
extension UIViewController {
func showAlert(title: String, message: String) {
let alertController = UIAlertController(title: title, message:
message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {_ in
}))
self.present(alertController, animated: true, completion: nil)
}
}
but I am not sure how to create extension which have target and textfield(how to create and call that in viewcontroller)
my code for which i am trying to create extension
let alertController = UIAlertController(title: "enter name", message: nil, preferredStyle: .alert)
let addAction = UIAlertAction(title: "Ok", style: .default) {_ in
guard let name = alertController.textFields?.first?.text else { return }
let newTask = Task(name: name)
self.toDoStore?.add(newTask, at: 0)
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.insertRows(at: [indexPath], with: .automatic)
}
addAction.isEnabled = false
let cancelAction = UIAlertAction(title: CANCEL_ACTION, style: .cancel, handler: nil)
alertController.addTextField { textField in
textField.placeholder = "enter name.."
textField.addTarget(self, action: #selector(self.handleTextChanged), for: .editingChanged)
}
alertController.addAction(addAction);
alertController.addAction(cancelAction);
present(alertController, animated: true, completion: nil)

You could try the below extension that I'm using made a few changes according to your requirements.
extension UIViewController {
func showAlert(_ title: String?,
message: String?,
actions: [String: UIAlertAction.Style] = [:],
handler: ((UIAlertAction) -> Void)? = nil,
textFields: [((UITextField) -> Void)] = []) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
if actions.isEmpty {
alert.addAction(UIAlertAction(title: "Okay", style: .default))
} else {
for action in actions {
alert.addAction(UIAlertAction(title: action.key, style: action.value, handler: handler))
}
}
for textField in textFields {
alert.addTextField(configurationHandler: textField)
}
present(alert, animated: true)
}
}
A bit of advise you can always check how the parameters that you pass are accepted by the system API and customize your own function in a similar way.

Related

alertview textField returning empty string

class x: UIViewController {
let fromLocationLbl = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
let editTextField = UITextField()
let alertController = UIAlertController(title: "Alert!", message: "Please enter from location", preferredStyle: .alert)
alertController.addTextField { editTextField in
editTextField.placeholder = "Enter correct name"
// editTextField.text = self.fromLocationLbl.text
}
let confirmAction = UIAlertAction(title: "Change", style: UIAlertActionStyle.default) { (UIAlertAction) in
print(editTextField.text) ///////printing optional("")
self.fromLocationLbl.text = editTextField.text
}
alertController.addAction(confirmAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
}
editTextField isn't the same UITextField as you're adding to alert. In addTextField closure, editTextField is just name for parameter of closure which can be replaced with any other name
alertController.addTextField { textField in
textField.placeholder = "Enter correct name"
// textField.text = self.fromLocationLbl.text
}
You need to get reference for first text field in your alertController
let confirmAction = UIAlertAction(title: "Change", style: .default) { _ in
self.fromLocationLbl.text = alertController.textFields?.first?.text
}

How to add message Phone call alert popup?l

I wanna add message to phone call alert popup.
how to make it?
enter image description here
Yes, you can do it like that:
func phoneCall(to phoneNumber:String) {
if let callURL:URL = URL(string: "tel:\(phoneNumber)") {
let application:UIApplication = UIApplication.shared
if (application.canOpenURL(callURL)) {
let alert = UIAlertController(title: "Your Title", message: "Do you want call that number?", preferredStyle: .alert)
let callAction = UIAlertAction(title: "Call", style: .default, handler: { (action) in
application.openURL(callURL)
})
let noAction = UIAlertAction(title: "No", style: .cancel, handler: { (action) in
print("Canceled Call")
})
alert.addAction(callAction)
alert.addAction(noAction)
self.present(alert, animated: true, completion: nil)
}
}
}

How to get the index of item selected in Alert of UIAlertController Swift

I am going to use UIAlertController for a user to select one item.
The items to select are array as following:
let arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney", ... ]
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .Alert)
// Add items in array to Alert
for var i = 0; i < arraySelect.count; i++ {
alert.addAction(UIAlertAction(title: arrayBibleVersions[i], style: .Default, handler: {(_) in }))
}
// Add cancel button.
alert.addAction(UIAlertAction(title: "취소", style: .Cancel, handler: {(_) in }))
self.presentViewController(alert, animated: false, completion: nil)
When a user touched one item, I have to get the index of the item that a user toched on.
But I don't know how to get the index..
Please help me.
I solved my question as following:
let arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney", ... ]
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .Alert)
let closure = { (action: UIAlertAction!) -> Void in
let index = alert.actions.indexOf(action)
if index != nil {
NSLog("Index: \(index!)")
}
}
for var i = 0; i < arrayBibleVersions.count; i++ {
alert.addAction(UIAlertAction(title: arrayBibleVersions[i][1], style: .Default, handler: closure))
}
alert.addAction(UIAlertAction(title: "cancel", style: .Cancel, handler: {(_) in }))
self.presentViewController(alert, animated: false, completion: nil)
This is how I solved it in Swift 4 / iOS11
projects.forEach { project in
alertController.addAction(
UIAlertAction(title: project.name, style: .default, handler: { action in
if let index = alertController.actions.index(where: { $0 === action }) {
self.showProject(project: projects[index])
}
})
)
}
I have the same problem too and found the method below which saved me.
But be careful if the item in array are the same, it will return the first item's index.
Fortunately, It's work in this case, because we create the action and using action to search.
extension Array where Self.Element : Equatable {
...
#inlinable public func index(of element: Element) -> Int?
...
}
It work in Swift 4
let arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney"]
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
// Add items in array to Alert
for name in arraySelect {
alert.addAction(UIAlertAction(title: name, style: .default, handler: {(action) in
// print idx that user selected
if let idx = alert.actions.index(of: action) {
print("idx = \(idx)")
}
}))
}
// Add cancel button.
alert.addAction(UIAlertAction(title: "취소", style: .cancel, handler: {(_) in }))
self.present(alert, animated: true, completion: nil)
This is working good:
var arraySelect = ["NewYork", "Washington", "Seoul", "Tokyo", "Peking", "Sidney"]
let alert = UIAlertController(title: nil, message: nil, preferredStyle: .Alert)
let closure = { (action: UIAlertAction!) -> Void in
let index = alert.actions.indexOf(action)
if index != nil {
NSLog("Index: \(index!)")
}
}
for field in arraySelect {
alert.addAction(UIAlertAction(title: field, style: .Default, handler: closure))
}
alert.addAction(UIAlertAction(title: "cancel", style: .Cancel, handler: {(_) in }))
self.presentViewController(alert, animated: false, completion: nil)
Block is executed when the user selects a action.
// Add cancel button.
alert.addAction(UIAlertAction(title: "취소", style: .Cancel, handler: {(_) in
//your code
}))
func FirefoxAhri(){
let optionMenu = UIAlertController(title: "title", message: "message", preferredStyle: UIAlertControllerStyle.ActionSheet)
let action1 = UIAlertAction(title: "Yes", style: UIAlertActionStyle.Destructive){
action -> Void in
//do stuff on click Yes
}
let action2 = UIAlertAction(title: "No", style: UIAlertActionStyle.Destructive){
action -> Void in
//do stuff on click No
}
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
print("Cancel")
// do nothing if you don't want. alert closes automatically
}
optionMenu.addAction(action1)
optionMenu.addAction(action2)
optionMenu.addAction(cancelAction)
self.presentViewController(optionMenu, animated: true, completion: nil)
}

UIAlertAction Error

I'm trying to add some actions to a UIAlertController but I am getting an error when I'm passing it a closure. I want to pass that closure as a handler for an action, but I am getting an error message.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
let optionMenu = UIAlertController(title: nil, message: "What do you want to do?", preferredStyle: .ActionSheet)
let cancel = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
optionMenu.addAction(cancel)
self.presentViewController(optionMenu, animated: true, completion: nil)
let callActionHandler = { (action:UIAlertAction) -> Void in
let alertMessage = UIAlertController(title: "No service", message: "Sorry the phone option is not working right now, try again later", preferredStyle: .Alert)
alertMessage.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil))
self.presentViewController(alertMessage, animated: true, completion: nil)
}
let callAction = UIAlertAction(title: "Call " + "123-000-\(indexPath.row)", style: UIAlertActionStyle.Default , handler: callActionHandler)
optionMenu.addAction(callAction)
}
Solved. Only ! you missed.
Change the below line
let callActionHandler = { (action:UIAlertAction) -> Void in
with
let callActionHandler = { (action:UIAlertAction!) -> Void in
That's it !

Swift: Insert Alert Box with Text Input (and Store Text Input )

In one of my viewController, I want to make an alert box appear that prompts the user to type this information.Then, I want the user to store this input using NSUserDefaults. How can I achieve this?
Thank you in advance!
Check this out:
let alertController = UIAlertController(title: "Email?", message: "Please input your email:", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Confirm", style: .default) { (_) in
guard let textFields = alertController.textFields,
textFields.count > 0 else {
// Could not find textfield
return
}
let field = textFields[0]
// store your data
UserDefaults.standard.set(field.text, forKey: "userEmail")
UserDefaults.standard.synchronize()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alertController.addTextField { (textField) in
textField.placeholder = "Email"
}
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
SWIFT 3
func presentAlert() {
let alertController = UIAlertController(title: "Email?", message: "Please input your email:", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Confirm", style: .default) { (_) in
if let emailTextField = alertController.textFields?[0] {
// do your stuff with emailTextField
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alertController.addTextField { (textField) in
textField.placeholder = "Email"
}
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
In swift 3
let alertController = UIAlertController(title: "SecureStyle", message: "SecureStyle AlertView.", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addTextFieldWithConfigurationHandler { (textField : UITextField) -> Void in
textField.secureTextEntry = true
textField.placeholder = "Password"
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { (result : UIAlertAction) -> Void in
print("Cancel")
}
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { (result : UIAlertAction) -> Void in
print(alertController.textFields?.first?.text)
}
alertController.addAction(cancelAction)
alertController.addAction(okAction)
self.presentViewController(alertController, animated: true, completion: nil)