Change UIAlertController message or title during its presentation - ios

Is posible change the title or message text of UIAlertController while its ViewController is presenting.
For example I present an alert when a user press a button with this message:
"Waiting for redeem code"
Then I use Alamofire to make a request and get the code, after I have it I want to change the message from alert without dissmising and presenting it again, for example the new message text is it:
"Your redeem code is : ########"
Updated
Here is my code:
#IBAction func offerAction(_ sender: UIButton) {
var code: String = "Generating códe"
let message: String = "El código para redimir esta oferta es: \(code)"
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Accept", style: .default, handler: nil)
let redirect = UIAlertAction(title: "Website", style: .default) { (_) in
// TODO open url web
}
if offer.redeemOfferOnline == .yes {
alert.addAction(redirect)
}
alert.addAction(okAction)
present(alert, animated: true, completion: nil)
offer.code.getRedeemCode(id: offer.id) { (success, data) in
if success {
code = data
alert.message = message
// TODO end the code of changing the message of alert
}
}
}

this is possible of course, please check the following:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let alertController = UIAlertController(title: "My Title", message: "My Message", preferredStyle: .alert)
present(alertController, animated: true, completion: nil)
// Do your queries and get your new title and then set the new title
alertController.title = "Your new title"
}
}

It is possible to change the title and/or text AND animate the change, thusly:
[UIView transitionWithView: alertController.view
duration: 0.3
options: UIViewAnimationOptionTransitionCrossDissolve
animations: ^(void) {
alertController.message = newMessage;
}
completion: nil];
Or in Swift:
UIView.transition(with: alertController.view,
duration: 0.3,
options: .transitionCrossDissolve,
animations: { alertController.message = newMessage }
)

Just define you alertcontroller as:
var controller:UIAlertController?
Then initialize your alert controller like this:
controller = UIAlertController(title: "Title", message: "Yo", preferredStyle: .alert)
self.present(controller!, animated: true, completion: nil)
Now when you get the data from server, call this:
self.controller?.title = "New Title"

displayMyAlertMessage(userMessage: "Keshav Gera");
func displayMyAlertMessage(userMessage: String)
{
let alert = UIAlertController(title: "Success", message: userMessage, preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
let imgTitle = UIImage(named:"imgTitle.png")
let imgViewTitle = UIImageView(frame: CGRect(x: 10, y: 10, width: 30, height: 30))
imgViewTitle.image = imgTitle
alert.view.addSubview(imgViewTitle)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}

Related

How to put a success or error alert inside an options alert?

I have a problem trying to put an alert message after completing the action. The application crashes.
#IBAction func deleteAccountAction(_ sender: Any) {
let userID = prefs.value(forKey: "userId") as! String
print("user id: \(userID)")
let alert = UIAlertController(title: "Delete account", message: "Are you sure you want to delete your account?, This action cannot be reversed.", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
// ...
}
let okayAction = UIAlertAction(title: "OK", style: .default) { (action) in
RestAPIManager.sharedInstance.deleteAccount(userID: userID){
(json, error) in
if(json != JSON.null){
print(json)
if(json["success"] == true){
//here i want succes alert
}else{
self.errorAlert()
}
}else{
}
}
}
alert.addAction(okayAction)
alert.addAction(cancelAction)
self.present(alert, animated: true)
}
func errorAlert(){
var dialogMessage = UIAlertController(title: "Error", message: "Error", preferredStyle: .alert)
self.present(dialogMessage, animated: true, completion: nil)
}
I tried to put an alert message after the action but I can't.
is solved needs to be async.
DispatchQueue.main.async {
self.errorAlert()
}

ViewController reloads on presenting alert controller swift

I am working on project. i have added a simple alertController on clicking signup button. when i click on the button my viewcontroller reloads and then it shows that alertController. It is happening on iOS 13 and swift 5 or above
let alert = UIAlertController(title: "Your title", message: "Your message", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: { action in
})
alert.addAction(ok)
let cancel = UIAlertAction(title: "Cancel", style: .default, handler: { action in
})
alert.addAction(cancel)
DispatchQueue.main.async(execute: {
self.present(alert, animated: true)
})
i resolved my problem by these lines of code
func alert(message: String, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let alertAction = UIAlertAction(title: "OK", style: .default) { (action) in
print("Action")
}
alertController.addAction(alertAction)
(UIApplication.shared.delegate as! AppDelegate).alertWindow.isHidden = true
self.presentViewController(alertController: alertController)
// self.present(alertController, animated: true, completion: nil)
}
func presentViewController(alertController: UIAlertController, completion: (() -> Void)? = nil) {
if var topController = UIApplication.shared.keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
DispatchQueue.main.async {
topController.present(alertController, animated: true, completion: completion)
}
}
}

Add an alertcontroller in a global swift file? [duplicate]

This question already has answers here:
how to create an alert in a swift file model that works for various view controller
(2 answers)
Closed 4 years ago.
I am trying to create a alert box inside the swift file other than the UIViewController file. but I could not create it.
extension NetworkManager {
func showAlert(message: String,from:UIViewController, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
from.present(alertController, animated: true, completion: nil)
}
}
the above code is for implementing alertcontroller but I don't know how to pass the view controller I need to present so need assistance.
extension UIViewController {
func showAlert(message: String, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
}
and use like this
from.showAlert(message:"Your message", title: "Title")
Add a Utilities class in your project.
class Utilities {
static func showSimpleAlert(OnViewController vc: UIViewController, Message message: String) {
//Create alertController object with specific message
let alertController = UIAlertController(title: "App Name", message: message, preferredStyle: .alert)
//Add OK button to alert and dismiss it on action
let alertAction = UIAlertAction(title: "OK", style: .default) { (action) in
alertController.dismiss(animated: true, completion: nil)
}
alertController.addAction(alertAction)
//Show alert to user
vc.present(alertController, animated: true, completion: nil)
}
}
Usage:
Utilities.showSimpleAlert(OnViewController: self, Message: "Some message")
Here is the extension I made. It allows to show either Alert or Action sheet and allows multiple actions "from the box"
extension UIViewController {
func presentAlert(title: String?, message: String, actions: UIAlertAction..., animated: Bool = true) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
actions.forEach { alert.addAction($0) }
self.present(alert, animated: animated, completion: nil)
}
func presentActionSheet(title: String?, message: String, actions: UIAlertAction..., animated: Bool = true) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .actionSheet)
actions.forEach { alert.addAction($0) }
self.present(alert, animated: animated, completion: nil)
}
}
Usage
let delete = UIAlertAction(title: "Delete", style: .destructive, handler: { _ in /* Your code here */})
let cancel = UIAlertAction(title: "Cancel", style: .default, handler: nil)
presentAlert(title: .albumPreferencesDeleteAlertTitle, message: "Very important message", actions: delete, cancel)
This is the more generalise method to show alert on view controller
func showAlert(msg: String, inViewController vc: UIViewController, actions: [UIAlertAction]? = nil, type: UIAlertControllerStyle = .alert, title: String = kAppName) {
let alertType: UIAlertControllerStyle = .alert
let alertTitle = kAppName
let alertVC = UIAlertController(title: alertTitle, message: msg, preferredStyle: alertType)
if let actions = actions {
for action in actions {
alertVC.addAction(action)
}
} else {
let actionCancel = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertVC.addAction(actionCancel)
}
vc.present(alertVC, animated: true, completion: nil)
}
Usage
AppUtilities.showAlert(msg: "Test msg", inViewController: self) //for alert
AppUtilities.showAlert(msg: "Test msg", inViewController: self, actions: [okAction, cancelAction]) //for alert
AppUtilities.showAlert(msg: "Test Msg", inViewController: self, type: .actionSheet) //shows action sheet
You can add this function in extension or create a separate utility class as you want.

Parse Password reset function

I am trying to use the password reset for parse in my ios app and I can't seem to find any tutorial on the best method in swift on how to implement this into a button action but find nothing.
Anyone know a great place to look?
This is what I have so far
#IBAction func resetPassword(sender: AnyObject) {
[PFUser requestPasswordResetForEmailInBackground:
self.loginEmail.text
block:^(BOOL succeeded, NSError *error)
{
[APP.hud hide:YES];
if (!succeeded)
{
NSString *msg = #"Could not connect. Try again later.";
[UIAlertView ok:msg];
return;
}
[UIAlertView minimalistMessageFor:3.0
title:nil
message:#"Your password has been sent to your email address."
then:^{ }];
[self begin];
}];
}
I get a Expected expression in container literal error on this one on the PFUser line.
I use the following in the app I'm working on, which pop ups a alert box to enter your email and confirms the result in a new alert box:
#IBAction func resetPasswordPressed(sender: AnyObject) {
let titlePrompt = UIAlertController(title: "Reset password",
message: "Enter the email you registered with:",
preferredStyle: .Alert)
var titleTextField: UITextField?
titlePrompt.addTextFieldWithConfigurationHandler { (textField) -> Void in
titleTextField = textField
textField.placeholder = "Email"
}
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
titlePrompt.addAction(cancelAction)
titlePrompt.addAction(UIAlertAction(title: "Reset", style: .Destructive, handler: { (action) -> Void in
if let textField = titleTextField {
self.resetPassword(textField.text)
}
}))
self.presentViewController(titlePrompt, animated: true, completion: nil)
}
func resetPassword(email : String){
// convert the email string to lower case
let emailToLowerCase = email.lowercaseString
// remove any whitespaces before and after the email address
let emailClean = emailToLowerCase.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
PFUser.requestPasswordResetForEmailInBackground(emailClean) { (success, error) -> Void in
if (error == nil) {
let success = UIAlertController(title: "Success", message: "Success! Check your email!", preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
success.addAction(okButton)
self.presentViewController(success, animated: false, completion: nil)
}else {
let errormessage = error!.userInfo!["error"] as! NSString
let error = UIAlertController(title: "Cannot complete request", message: errormessage as String, preferredStyle: .Alert)
let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil)
error.addAction(okButton)
self.presentViewController(error, animated: false, completion: nil)
}
}
}
It's also smart to convert the email users register with to lowercase before you sync it with parse in a similar way as I show with the reset method.
If you want to put in a activity indicator, so that users see that the app is busy in between the actions, create the following two methods and call Pause() in the Reset action and Restore() just before or after the if/else in the resetPassword method. Also include the following class variable:
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
func pause(){
activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 50, 50))
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
}
func restore(){
activityIndicator.stopAnimating()
UIApplication.sharedApplication().endIgnoringInteractionEvents()
}
It looks like you are mixing up swift with objective-c. I'm assuming that you are in a swift class. Try the following:
#IBAction func resetPassword(sender: AnyObject) {
PFUser.requestPasswordResetForEmailInBackground(self.loginEmail.text)
var alert = UIAlertController(title: nil, message: "Your password has been sent to your email address.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
I had a similar problem, the problem is that the doc is apparently not updated on that
PFUser.requestPasswordResetForEmailInBackground("email#example.com")
The following thing worked for me
PFUser.requestPasswordResetForEmailInBackground("email#example.com", nil)
Hope that this will help

Changing screens by alert in swift

I have no idea how to change screens programatically. I have an alert view and I want to be able to change screen when the user presses the "Ok" button. How do I do this?
Here is my new code:
func showAlertController(){
let tilte = "My Medication"
let message = NSLocalizedString("Go through Medication guide?", comment: "")
let cancelButtonTitle = NSLocalizedString("Dismiss", comment: "")
let otherButtonTitle = NSLocalizedString("Ok", comment: "")
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .Cancel){ action in
NSLog("User said no")}
let otherAction = UIAlertAction(title: otherButtonTitle, style: .Default){action in
// I know I need to put something in here.
let appointment = Appointment()
self.presentViewController(appointment, animated:true, completion:nil)
}
alertController.addAction(cancelAction)
alertController.addAction(otherAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
However now I get a bug saying:
Thread 1: EXC_BAD_INSTRUCTION(code=EXC_l1386_INVOP,subcode=0x0)
Add presentViewController inside UIAlertAction closure for "Ok" button, it means that the button is pressed and so you do your stuffs for the button being pressed inside the block.
class MainViewController: UIViewController {
...
...
func showAlertController(){
let tilte = "My Medication"
let message = NSLocalizedString("Go through Medication guide?", comment: "")
let cancelButtonTitle = NSLocalizedString("Dismiss", comment: "")
let otherButtonTitle = NSLocalizedString("Ok", comment: "")
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .Cancel){ action in
NSLog("User said no")}
let otherAction = UIAlertAction(title: otherButtonTitle, style: .Default){action in
// I know I need to put something in here.
let appointmentViewController = AppointmentViewController()
self.presentViewController(appointmentViewController, animated:true, completion:nil)
}
alertController.addAction(cancelAction)
alertController.addAction(otherAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
...
...
}
class AppointmentViewController: UIViewController {
}

Resources