Making a calculator in Swift - ios

My problem is that I can click and input multiple numbers for my first value but then after I used a math operator (ex. +,-,*,/) it only allows me to input a single value unlike the first time running it.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Label: UILabel!
var secondNumber: Double = 0;
var firstNumber: Double = 0;
var performingMath = false
var operatorUsed = 0;
#IBAction func cleartext(_ sender: UIButton) {
Label.text = ""
performingMath = false
}
#IBAction func Numbers(_ sender: UIButton) {
if performingMath {
Label.text = String(sender.tag - 1)
secondNumber = Double(Label.text!)!
performingMath = true
} else {
Label.text = Label.text! + String(sender.tag - 1)
secondNumber = Double(Label.text!)!
}
}
#IBAction func Operators(_ sender: UIButton) {
if Label.text != " " && sender.tag != 11 {
firstNumber = Double(Label.text!)!
if sender.tag == 12 {
Label.text = "+"
} else if sender.tag == 13 {
Label.text = "-"
} else if sender.tag == 14 {
Label.text = "*"
} else if sender.tag == 15 {
Label.text = "/"
}
operatorUsed = sender.tag
performingMath = true
} else if sender.tag == 11 {
if operatorUsed == 12 {
Label.text = String(firstNumber + secondNumber)
}
if operatorUsed == 13 {
Label.text = String(firstNumber - secondNumber)
}
if operatorUsed == 14 {
Label.text = String(firstNumber * secondNumber)
}
if operatorUsed == 15 {
Label.text = String(firstNumber / secondNumber)
}
}
}
}
I expect the that I can input many values as possible after I used a math operator (ex. +-*/)

When you update the label's text when performingMath is true, you just assign the new value instead of adding the value to the existing one (see line 3)
#IBAction func Numbers(_ sender: UIButton) {
if performingMath {
Label.text = String(sender.tag - 1) // !! HERE !!
secondNumber = Double(Label.text!)!
performingMath = true
} else {
Label.text = Label.text! + String(sender.tag - 1)
secondNumber = Double(Label.text!)!
}
}
This should perform the same action as when performingMath is false, so you just need to update this line with:
Label.text = Label.text! + String(sender.tag - 1)

Related

What am I missing when calculating?

I am pretty new with programming but I am currently learning iOS. I have been trying to build a calculator but I have some problems. For instance, when I try to calculate 2 + 2, it shows me 5. Because when I press the second number (in this case 2) it makes it 3.
Can anyone help me to fix and understand the problem?
import UIKit
class ViewController: UIViewController {
var numberOnScreen:Double = 0
var previousNumber:Double = 0
var performingMath = false
var operation = 0
#IBOutlet weak var label: UILabel!
#IBAction func numbers(_ sender: UIButton)
{
if performingMath == true
{
label.text = String(sender.tag)
numberOnScreen = Double(label.text!)!
performingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Double(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton)
{
if label.text != "" && sender.tag != 11 && sender.tag != 16
{
previousNumber = Double(label.text!)!
if sender.tag == 12 {
label.text = "/"
}
else if sender.tag == 13 {
label.text = "*"
}
else if sender.tag == 14 {
label.text = "-"
}
else if sender.tag == 15 {
label.text = "+"
}
operation = sender.tag
performingMath = true
}
else if sender.tag == 16 {
if operation == 12 {
label.text = String(numberOnScreen / previousNumber)
}
else if operation == 13 {
label.text = String(numberOnScreen * previousNumber)
}
else if operation == 14 {
label.text = String(numberOnScreen - previousNumber)
}
else if operation == 15 {
label.text = String(numberOnScreen + previousNumber)
}
}
else if sender.tag == 11 {
label.text = ""
numberOnScreen = 0
previousNumber = 0
operation = 0
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}

Add a decimal to calculator app swift 4

I need help where to add the decimal function in the following code? I found the same question that had the same code but the corrections did not work. Looking for any help here!
Here is my code:
#IBOutlet weak var label: UILabel!
#IBAction func numbers(_ sender: UIButton) {
if performingMath == true {
label.text = String(sender.tag-1)
numberOnScreen = Double(label.text!)!
performingMath = false
}
else {
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Double(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 11 && sender.tag != 16{
previousNumber = Double(label.text!)!
if sender.tag == 12 { //Divide
label.text = "/";
}
}
There is more code below with the other func buttons (multiply, add, subtract, etc...)
I appreciate any help!
I would add another button for the decimal point. You would need to check that pressing a decimal point made sense. For example:
if label.text == "" {
// Decimal at the start means add a zero
label.text = "0."
} else if label.text.contains(".") {
// Don’t add another decimal point!
}
// To get number from label
if let number = Double(label.text) {
// Use the number here
}

Change a button background on click of another button

I use this code so that when I click on a button its background changes to a picture with a white border and when I press it again it changes to a picture with a gray background (the button always has a gray background).
How can I do so that when I click on another button (clear and equal), the background of the "+", "-", "/", "*" changes to gray as it was before pressing.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var displayResultLabel: UILabel!
var stillTyping = false
var dotIsPlaced = false
var firstOperand: Double = 0
var secondOperand: Double = 0
var operationSign: String = ""
var currentInput: Double {
get {
return Double (displayResultLabel.text!)!
}
set {
let value = "\(newValue)"
let ValueArray = (value.components(separatedBy:"."))
if ValueArray[1] == "0" {
displayResultLabel.text = "\(ValueArray[0])"
} else {
displayResultLabel.text = "\(newValue)"
}
stillTyping = false
}
}
#IBAction func numberPressed(_ sender: UIButton) {
let number = sender.currentTitle!
if stillTyping {
if (displayResultLabel.text?.characters.count)! < 20 {
displayResultLabel.text = displayResultLabel.text! + number
}
} else {
displayResultLabel.text = number
stillTyping = true
}
}
#IBAction func twoOperandsSignPressed(sender: UIButton) {
operationSign = sender.currentTitle!
firstOperand = currentInput
stillTyping = false
dotIsPlaced = false
}
func operateWithTwoOperands(operation: (Double, Double) -> Double) {
currentInput = operation(firstOperand, secondOperand)
stillTyping = false
}
#IBAction func equalitySignPressed(sender: UIButton) {
if stillTyping {
secondOperand = currentInput
}
dotIsPlaced = false
switch operationSign {
case "+":
operateWithTwoOperands{$0 + $1}
case "-":
operateWithTwoOperands{$0 - $1}
case "✕":
operateWithTwoOperands{$0 * $1}
case "÷":
operateWithTwoOperands{$0 / $1}
default: break
}
}
#IBAction func clearButtonPressed(_ sender: UIButton) {
firstOperand = 0
secondOperand = 0
currentInput = 0
displayResultLabel.text = "0"
dotIsPlaced = false
operationSign = ""
}
// +,-
#IBAction func plusMinusButtonPressed(_ sender: UIButton) {
currentInput = -currentInput
}
#IBAction func percentageButtonPressed(_ sender: UIButton) {
if firstOperand == 0 {
currentInput = currentInput / 100
} else {
secondOperand = firstOperand * currentInput / 100
}
}
#IBAction func squareRootButtonPressed(_ sender: UIButton) {
currentInput = sqrt(currentInput)
}
#IBAction func dotButtonPressed(_ sender: UIButton) {
if stillTyping && !dotIsPlaced {
displayResultLabel.text = displayResultLabel.text! + "."
dotIsPlaced = true
} else if !stillTyping && !dotIsPlaced {
displayResultLabel.text = "0."
}
#IBAction func PercentAnimate(_ sender: UIButton) {
if sender.currentBackgroundImage == image_off {
sender.setBackgroundImage(Image_on, for: .normal)
} else {
sender.setBackgroundImage(image_off, for: .normal)
}
if (previousButton !== sender) {
previousButton.setBackgroundImage(image_off, for: .normal)
previousButton = sender
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Here is the code you can Create border to any View, in your case it will be button.
func createBordersWithColor(color: UIColor, myView : UIView) {
myView.layer.borderWidth = 1
myView.layer.cornerRadius = 0
myView.layer.shouldRasterize = false
myView.layer.rasterizationScale = 2
myView.clipsToBounds = true
myView.layer.masksToBounds = true
let cgColor: CGColor = color.cgColor
myView.layer.borderColor = cgColor
}
You can use the above function with you code like
#IBAction func PercentAnimate(_ sender: UIButton) {
let btnCurrent : UIButton = sender as! UIButton
let btnPrevious : UIButton = previousButton as! UIButton
createBorderWithColor(color : UIColor.clear , myView : btnPrevious)
createBorderWithColor(color : UIColor.clear , myView : btnCurrent)
if (previousButton !== sender) {
previousButton = sender
}
}
let know if it helps, or you need any explanation.
If you want to set with image
#IBAction func PercentAnimate(_ sender: UIButton) {
let btnCurrent : UIButton = sender as! UIButton
let btnPrevious : UIButton = previousButton as! UIButton
btnPrevious.setBackgroundImage(image_off, for: .normal)
btnCurrent.setBackgroundImage(image_on, for: .normal)
if (previousButton !== sender) {
previousButton = sender
}
}

Creating a class that does all of the functions of the viewcontroller

I am attempting to make my calculator function look more organized. I have decided to create a calculator class that does all of the functions. Currently this is not working, my only problem is that I make a new instance of a class every time a number is pressed, this happens because I dont know what number is going to be pressed next so I cannot define LBLOutput in my constructor until It is passed to me. Here are my two files
The problem lies where I am calling the cb.functions. Currently they work but only one number can show up on the screen at a time due to the fact that a new class is declared every time.
Is this a viable way of making the calculator? Do i need to just start from scratch?
//
// ViewController.swift
// MyCalculator
//
// Created by Kevin Maldjian on 2/6/17.
// Copyright © 2017 Kevin Maldjian. All rights reserved.
//
import UIKit
import Foundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBOutlet weak var LBLOutput: UILabel!
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func btrNumberClick(_ sender: UIButton) {
let cb = calculatorBrain(LBLOutput: LBLOutput , sender: sender)
cb.btrNumberClick()
}
#IBAction func clearTheLabel(_ sender: Any) {
let cb = calculatorBrain(LBLOutput: LBLOutput, sender: sender as! UIButton)
cb.clearTheLabel()
}
#IBAction func goNegative(_ sender: Any){
let cb = calculatorBrain(LBLOutput: LBLOutput, sender: sender as! UIButton)
cb.goNegative()
}
#IBAction func squareRoot(_ sender: Any) {
let cb = calculatorBrain(LBLOutput: LBLOutput, sender: sender as! UIButton)
cb.squareRoot()
}
}
THE MAIN FUNCTIONS ARE DONE HERE
//
// calculatorBrain.swift
// SalvageAttempt
//
// Created by Kevin Maldjian on 3/13/17.
// Copyright © 2017 Kevin Maldjian. All rights reserved.
//
import Foundation
import UIKit
class calculatorBrain
{
var num1 = ""
var num2 = ""
var finalString = ""
var isFirstNumber = true
var safeToAdd = true
var hasFinalString = false
var isClear = true
var hasDecimal = false
var doubleChecker = 0
var hasSecondDecimal = false
var LBLOutput = UILabel()
var sender = UIButton()
init(LBLOutput : UILabel, sender : UIButton) {
self.num1 = " "
self.num2 = " "
self.finalString = ""
self.isFirstNumber = true
self.safeToAdd = true
self.hasFinalString = false
self.isClear = true
self.hasDecimal = false
self.doubleChecker = 0
self.hasSecondDecimal = false
self.LBLOutput = LBLOutput
self.sender = sender
}
func btrNumberClick() {
if isClear {
LBLOutput.text = ""
isClear = false
}
let currentText = LBLOutput.text!
let textLabel = sender.titleLabel?.text
if let text = textLabel {
switch text {
case "+", "x", "/", "-","%":
if hasFinalString {
return
}
finalString = text
isFirstNumber = false
hasFinalString = true
safeToAdd = true
LBLOutput.text = "\(currentText) \(finalString) "
break
case "=":
if !hasFinalString
{break}
isFirstNumber = true
hasFinalString = false
isClear = true
var result = calculate()
if result.truncatingRemainder(dividingBy:1) == 0
{
result = (result)
}
LBLOutput.text = "\(result)"
num1 = "\(result)"
safeToAdd = false
hasSecondDecimal = false
hasDecimal = false
break
case ".":
if !safeToAdd{
num1 = ""
LBLOutput.text = ""
num1 = "\(num1)\(text)"
LBLOutput.text = LBLOutput.text! + num1
safeToAdd = true
} else if isFirstNumber{
if hasDecimal
{break}
LBLOutput.text = ""
num1 = "\(num1)\(text)"
LBLOutput.text = LBLOutput.text! + num1
hasDecimal = true
}else{
if hasSecondDecimal
{break}
num2 = "\(num2)\(text)"
LBLOutput.text = "\(currentText)\(text)"
hasSecondDecimal = true
}
break
default:
if !safeToAdd{
num1 = ""
LBLOutput.text = ""
num1 = "\(num1)\(text)"
LBLOutput.text = LBLOutput.text! + num1
safeToAdd = true
} else if isFirstNumber{
LBLOutput.text = ""
num1 = "\(num1)\(text)"
LBLOutput.text = LBLOutput.text! + num1
}else{ num2 = "\(num2)\(text)"
LBLOutput.text = "\(currentText)\(text)"
}
break;
}
}
}
func goNegative(){
var negativeChecker = Double(num1)!
if negativeChecker > 0
{ num1 = ("-" + num1)
LBLOutput.text = num1
}else{
negativeChecker = (-2 * negativeChecker) + negativeChecker
num1 = String(negativeChecker)
LBLOutput.text = String(negativeChecker)
}
}
func squareRoot() {
let squareRootX = sqrt(Double(LBLOutput.text!)!)
num1 = String(squareRootX)
LBLOutput.text = String(squareRootX)
}
#IBAction func clearTheLabel() {
num1 = ""
num2 = ""
LBLOutput.text = "0"
isClear = true
}
func calculate() -> Double {
let firstNumber = Double(self.num1)!
let secondNumber = Double(self.num2)!
num1 = ""
num2 = ""
self.isClear = false
switch finalString {
case "+":
return firstNumber + secondNumber
case "-":
return firstNumber - secondNumber
case "x":
return firstNumber * secondNumber
case "/":
return firstNumber / secondNumber
case "%":
return (firstNumber * 100) / secondNumber
default:
return 0
}
}
}
Move all of your functions out of this class called "calculatorBrain". Just make them public, or in the case of a separate target (like a Framework) open. For instance:
class MyVC:UIViewController {
let a:Float = 1.0
let b:Float = 1.0
let currentSum = sum(a,b)
print(currentSum) // displays 2.0
}
In a separate file:
public sum(var1:Float, var2:Float) {
return var1+var2
}
Not much more to it. Again, remove everything from a class and you won't need an instance.

How to code a calculator that adds, numbers consecutively (Swift)

This is my code for the calculator, right now I can only add 2 numbers consecutively before hitting the equals sign, I want to make where I can add More than two Numbers before hitting the equals button. (Written in Swift)
import UIKit
class CalcControl: UIView {
var firstEntry = ""
var isUserInMiddleOfTypingNumbers:Bool?
var didUserPressedOperation:Bool?
var op:String?
#IBOutlet var displayLabel: UILabel!
#IBAction func digitPressed(sender: UIButton) {
if (didUserPressedOperation == nil) {
//displayLabel.text = ""
didUserPressedOperation = nil
}
if (isUserInMiddleOfTypingNumbers == nil) {
displayLabel.text = displayLabel.text! + sender.currentTitle!
} else {
displayLabel.text = sender.currentTitle
isUserInMiddleOfTypingNumbers = true
}
}
#IBAction func operationPressed(sender: UIButton) {
op = sender.currentTitle
firstEntry = displayLabel.text!
didUserPressedOperation = true
displayLabel.text = ""
}
#IBAction func clearPressed(sender: UIButton) {
self.clear()
}
func clear() {
firstEntry = ""
isUserInMiddleOfTypingNumbers = nil
didUserPressedOperation = nil
displayLabel.text = ""
}
#IBAction func equalPressed(sender: UIButton) {
var secondEntry:NSString = displayLabel.text!
println((firstEntry))
println((secondEntry))
if(op == "+") {
displayLabel.text = (((firstEntry as NSString!).doubleValue + (secondEntry as NSString).doubleValue) as NSNumber).stringValue
} else if(op == "-") {
displayLabel.text = (((firstEntry as NSString!).doubleValue - (secondEntry as NSString).doubleValue) as NSNumber).stringValue
} else if(op == "x") {
displayLabel.text = (((firstEntry as NSString!).doubleValue * (secondEntry as NSString).doubleValue) as NSNumber).stringValue
} else if(op == "/") {
displayLabel.text = (((firstEntry as NSString!).doubleValue / (secondEntry as NSString).doubleValue) as NSNumber).stringValue
}
firstEntry = ""
isUserInMiddleOfTypingNumbers = nil
didUserPressedOperation = nil
}
}
I would adjust your logic so that:
There is an IB Action that all the operator keys (+, -, x, /) are tied to. In this IB Action any time it is activated, there are two choices: a) prepare for another number to be entered or b) the previous key sequence was a number followed by an operator symbol and the button is the same as an Enter.
An IB Action for the delete key. Obvious role.
An IB Action for the Enter key.

Resources