简体   繁体   中英

Detect when a button is pressed outside of the IBAction in Swift?

I'm a beginner programmer making my first real app, a calculator in Swift.

It's mostly working, but one issue I'm running into is how it displays numbers after pressing one of the operator buttons. Currently, whenever an operator button is pressed, I have it set the label at the top of the calculator to "0". But on actual calculators, this top display won't change until another number button is pressed.

If I don't reset the display to 0, then any number buttons that are pressed will add to the current text at the top, and mess up the equation that the calculator will have to do (ie 2+2 displays 22, and the solution it displays is 22+2=24)

I'm wondering if it's possible to detect when one of the number buttons is pressed (listed in my code as the intButtonPressed IBAction) outside of the intButtonPressed function? That way I can keep the top label the same until the user starts inputting more text, then I can set it to 0 to prevent the calculator from breaking.

Any other possible (better) solutions would be welcome as well

Here's my code:

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var topLabel: UILabel!
    
    var num1 = Double()
    var solution = Double()
    var op = String()
    
    @IBAction func intButtonPressed(_ sender: UIButton) {
        if topLabel.text == "0" {
            topLabel.text = sender.currentTitle
        }
        else if topLabel.text == String(solution) {
            num1 = Double(topLabel.text!)!
            solution = 0.00
            topLabel.text = sender.currentTitle
                // Basically stops user from adding to solution?
                // Also stores solution as num1 and clears solution field
        }
        else {
            topLabel.text = topLabel.text! + sender.currentTitle!
            // Keep typing
        }
        
        if (topLabel.text?.count)! > 12 {
            topLabel.text = "Error"
        }
        else {
            return
        }
        // if its greater than 12 characters, display "error"
    }

    @IBAction func clearButtonPressed(_ sender: UIButton) {
        num1 = 0.00
        solution = 0.00
        topLabel.text = "0"
    }
    
    @IBAction func opButtonPressed(_ sender: UIButton) {
        if sender.currentTitle == "=" {
            equals()
        }
        else {
            op = sender.currentTitle!
            num1 = Double(topLabel.text!)!
            topLabel.text = "0"
        }
        // Need it to display num1 until I press another button, then I need it to only display that text.
    }
    
    func equals() {
        switch op {
        case "+":
            add()
        case "-":
            subtract()
        case "×":
            multiply()
        case "÷":
            divide()
        default:
            print(Error.self)
        }
    }
    
    func add() {
        solution = num1 + Double(topLabel.text!)!
        topLabel.text = String(solution)
    }
    
    func subtract() {
        solution = num1 - Double(topLabel.text!)!
        topLabel.text = String(solution)
    }
    
    func multiply() {
        print("topLabel = ", topLabel.text!)
        solution = num1 * Double(topLabel.text!)!
        print("solution = ", solution)
        topLabel.text = String(solution)
    }
    
    func divide() {
        solution = num1 / Double(topLabel.text!)!
        //answer()
    }
}

Update for anyone who finds this in the future: I've solved the issue, and realized that I wasn't very clear with what I wanted it to do. I solved the problem simply by adding a condition to the if/else statement in the inButtonPressed function that detects if the topLabel is 0. By rewriting that to detect if the topLabel is 0 OR the same as num1, and then changing the else statement in the opButtonPressed function to set topLabel to String(num1), the program does exactly what I want. Here's the rewritten code:

@IBAction func intButtonPressed(_ sender: UIButton) {
        if topLabel.text == "0" || topLabel.text == "0.0" || topLabel.text == String(num1){
            dotPressed = false
            // Resets dotPressed whenever the top is 0 or num1 and an int button is pressed
            topLabel.text = sender.currentTitle
        }
        else if topLabel.text == String(solution) {
            num1 = Double(topLabel.text!)!
            solution = 0.00
            topLabel.text = sender.currentTitle
                // Basically stops user from adding to solution?
                // Also stores solution as num1 and clears solution field
        }
        else {
            topLabel.text = topLabel.text! + sender.currentTitle!
        }
}

@IBAction func opButtonPressed(_ sender: UIButton) {
        
        if sender.currentTitle == "=" {
            equals()
        }
        else {
            op = sender.currentTitle!
            num1 = Double(topLabel.text!)!
            topLabel.text = String(num1)
        }
        // Successfully displays num1 until I press another button, then only displays that text.

I also added a separate function to handle decimals, and I had to update the code in there as well to keep that working.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM