help with the code below

Asked

Viewed 60 times

-1

Good afternoon, you guys!

I’m trying to make an app and I can’t do the programming so it doesn’t go to the next field with the empty field. The way the code is left blank and press to calculate the system closes.

I believe that because of the conversion, because if I leave in a normal way the keyboard for being Portuguese does not accept the comma, then I had to do the conversion.

If any of you can help me, I’d appreciate it!

Below the code, complete.

import UIKit

class MediasViewController: UIViewController {

    @IBOutlet weak var Litros: UITextField!
    @IBOutlet weak var MKhini: UITextField!
    @IBOutlet weak var Mkhfin: UITextField!
    @IBOutlet weak var MresultadoKh: UITextField!

    @IBAction func btnMedia(_ sender: UIButton) {

        let LitrosGeral = Double(self.Litros.text!)!
        let formatter = NumberFormatter()

        func convertToDouble (_ string: String) -> Double {
            formatter.numberStyle = .none
            return formatter.number(from: string)!.doubleValue
        }

        formatter.usesGroupingSeparator = true
        let Mkhini = convertToDouble(MKhini.text!)

        let Mkhfina = convertToDouble(Mkhfin.text!)
        var resultadoMediakh = (Mkhini - Mkhfina) * 17.8 * LitrosGeral

        if resultadoMediakh / 79.8 < 0 {
            (resultadoMediakh = 0)
        } else {
            resultadoMediakh = (resultadoMediakh / 79.8) / 3
        }
        MresultadoKh.text = String (format: "%.1f", resultadoMediakh)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        let alerta = UIAlertController (title: "Alerta", message: "teste", preferredStyle: .alert)

        let confirmar = UIAlertAction(title: "OK", style: .default, handler: nil)
        alerta.addAction(confirmar)

        present(alerta, animated: true, completion: nil)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }
}

1 answer

1

Yes the error occurs in the conversion because it cannot convert an empty field to a number and Voce is forcing it using ! What you can do is change

   let LitrosGeral = Double(self.Litros.text!)!

for

   let LitrosGeral = Double(self.Litros.text!) ?? 0

So every time the field is empty he will consider as 0

Now in order not to pass to the next field with the current field empty you must implement the function

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {...}

of the protocol UITextFieldDelegate, this function will be called each time a character is entered in a textfield that is set delegate with your Viewcontroller, so don’t forget to set this way:

   Litros.delegate = self

Following the code with the validation of each textfield to enable the next:

import UIKit

class MediasViewController: UIViewController {

    @IBOutlet weak var Litros: UITextField!
    @IBOutlet weak var MKhini: UITextField!
    @IBOutlet weak var Mkhfin: UITextField!
    @IBOutlet weak var MresultadoKh: UITextField!
    @IBOutlet weak var calculateButton: UIButton!

    @IBAction func btnMedia(_ sender: UIButton) {

        let LitrosGeral = Double(self.Litros.text!) ?? 0
        let Mkhini = Double(MKhini.text!) ?? 0
        let Mkhfina = Double(Mkhfin.text!) ?? 0

        var resultadoMediakh = (Mkhini - Mkhfina) * 17.8 * LitrosGeral

        if resultadoMediakh / 79.8 < 0 {
            (resultadoMediakh = 0)
        } else {
            resultadoMediakh = (resultadoMediakh / 79.8) / 3
        }
        MresultadoKh.text = String (format: "%.1f", resultadoMediakh)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        Litros.delegate = self
        MKhini.delegate = self
        Mkhfin.delegate = self
        MresultadoKh.delegate = self

        MKhini.isUserInteractionEnabled = false
        Mkhfin.isUserInteractionEnabled = false
        MresultadoKh.isUserInteractionEnabled = false
        calculateButton.isUserInteractionEnabled = false
    }

    // função para liberar o próximo TextField conforme ir completando
    func checkTextField() {
        let litrosCompleted = Litros.text!.count >= 1
        let iniCompleted = MKhini.text!.count >= 1
        let finCompleted = Mkhfin.text!.count >= 1

        if (litrosCompleted && !iniCompleted && !finCompleted) {
            MKhini.isUserInteractionEnabled = true
        } else if (litrosCompleted && iniCompleted && !finCompleted) {
            Mkhfin.isUserInteractionEnabled = true
        } else if (litrosCompleted && iniCompleted && finCompleted) {
            calculateButton.isUserInteractionEnabled = true
        }
    }
}

extension MediasViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        checkTextField()
        return true
    }
}

Remembering that this is just a simple example of how it can be done and that this code does not treat if the user goes back to the first field and deletes it, but if the user does this the app will run normally because every empty field is being treated with the value 0, A next step would be to treat Voce every time it is deleted the entire field the application complete with 0.

Also make sure that the Content Type of the keyboard is of the numeric type so that no letters can be typed in Textfield

Browser other questions tagged

You are not signed in. Login or sign up in order to post.