0

I'm extremely new to iOS. I'm trying to show a dialog to the user to get some input, but the actions are never triggered. I've been searching on the net for hours and no answer seem to work for me.

Here's the function I'm trying to use to show the dialog:

private func showAmountDialog(type: String, onComplete: @escaping (Double) -> Void) {
    let alert = UIAlertController(title: "Enter an amount", message: nil, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: LzStrings.Common_Cancel, style: .cancel, handler: nil))

    alert.addTextField(configurationHandler: { textField in
        textField.placeholder = "0.00 \(type)"
        textField.keyboardType = .decimalPad
    })

    alert.addAction(UIAlertAction(title: LzStrings.Common_OK, style: .default) { (UIAlertAction) in
        if let input = alert.textFields?.first?.text, let amount = Double(input) {
            print("Your amount: \(amount)")
        }
    })

    self.present(alert, animated: true)
}

self here is my ViewController which has a parent of UIViewController type and several other protocols.

What I might be doing wrong?

EDIT: The way I knew it isn't executing is using break-points and not by relying on print("...")

Also, since I added the TextField right before adding the action, the nullability check is useless and the textFields.first is never nil, so in both cases, a break-point should be triggered or the print("...") should be executed, which neither of them is happening.

EDIT 2: Since the if statement can do a little distraction, I edited my code this way and tested again:

 alert.addAction(UIAlertAction(title: LzStrings.Common_OK, style: .default) { (UIAlertAction) in
        if let input = alert.textFields?.first {
            if let amount = Double(input.text ?? "") {
                print("Your amount: \(amount)")
            } else {
                print("Can't cast this string to double")
            }
        } else {
            print("Text field is null")
        }
    })

Still, no feedback from the dialog. PS: Even the Cancel button doesn't work.

EDIT 3: My dismiss function is overridden in the super class, but it passes completion closure normally:

 override open func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
    if let navigationController = self.navigationController as? NavigationController {
        navigationController.dismiss(animated: flag, completion: completion)
    } else {
        super.dismiss(animated: flag, completion: completion)
    }
}
Tamim Attafi
  • 2,253
  • 2
  • 17
  • 34
  • It's not working because `print("Your amount: \(amount)")` isn't printed right? Well, is it because `alert.textFields?.first?.text` is nil, or because `Double(input)` is nil? – Larme Apr 23 '20 at 17:29
  • As @Larme said, why do you think it's working? – Mo Abdul-Hameed Apr 23 '20 at 17:57
  • @Larme, I didn't rely on the output of print(), I put a breakpoint right on the nullability checking line – Tamim Attafi Apr 23 '20 at 18:27
  • I edited the question – Tamim Attafi Apr 23 '20 at 18:31
  • `let amount = Double(input)` is that nil? Is that the cause of the fail? Could you replace your `if let ... {}` with `if let ... {} else { print("oops") }`? – Larme Apr 23 '20 at 20:58
  • @Larme, The if statement is not even executed. Please read my Edit, I'm not relying on printing, but on break points. – Tamim Attafi Apr 24 '20 at 06:00
  • @Larme, I edited my question, please check it out. – Tamim Attafi Apr 24 '20 at 06:08
  • https://stackoverflow.com/questions/31696643/uialertaction-handler-is-not-called ? https://stackoverflow.com/questions/30853387/uialertaction-completion-block-not-called-ios? Did you override dismiss method? – Larme Apr 24 '20 at 07:31
  • @Larme, for the first link, please check EDIT 3. For the second one I'm using Swift, not Objective-C – Tamim Attafi Apr 24 '20 at 07:40
  • "For the second one": It's the same reason, jsut in Objective-C. It doesn't matter it's the same framework behind, same logic. And what if you comment that line just to check if that fix it, and then we'll focus on that overridden method? – Larme Apr 24 '20 at 07:44
  • I'm extremely new to iOS, I can barely write swift code, I cannot understand Objective-C that's why I didn't include it in my tags) – Tamim Attafi Apr 24 '20 at 08:01

2 Answers2

0

After having a conversation with one of my colleagues, we found out that to show standard UIAlertController we must use this:

self.view.window!.rootViewController?.present(alert, animated: true, completion: nil)

Instead of this

self.present(alert, animated: true, completion: nil)

It fixed my issue. I hope someone will find this helpful.

Tamim Attafi
  • 2,253
  • 2
  • 17
  • 34
0

Another option is to use an extention for ViewController:

extension UIViewController {
    //Show a basic alert
    func showAlert(alertText : String, alertMessage : String) {
        let alert = UIAlertController(title: alertText, message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "Got it", style: UIAlertActionStyle.default, handler: nil))
        //Add more actions as you see fit
        self.present(alert, animated: true, completion: nil)
    }
}
cvld
  • 77
  • 1
  • 6