error - EXC_BREAKPOINT (code=1, subcode=0x100308448)
Every time I try to double-click the divide button, Xcode issues EXC_BREAKPOINT (code = 1, subcode = 0x100308448), and my application crashes. Can you please help me solving this issue?
Dividing button - EXC_BREAKPOINT(...)
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."
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Too bad that $0 can be only Int, not Double.
You should to describe in-line functions in detail like following.
operateWithTwoOperands {first, second in return first / second;}
Thank you for reading.
Related
I have code for my simple calculator.
How can I make the division of thousands so that when you enter numbers they are automatically separated by a dot?
For example:
Before:
1000000
After:
1.000.000
Code for calculator:
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)! < 14 {
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
}
You should use this extension, which works with NumberFormatter:
struct Number {
static let formatterWithDots: NumberFormatter = {
let formatter = NumberFormatter()
formatter.groupingSeparator = "." // only include this if you want to use dots regardless of the locale
formatter.numberStyle = .decimal
return formatter
}()
}
extension Double {
var formattedWithDots: String? {
return Number.formatterWithDots.string(from: self as NSNumber)
}
}
Usage:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(textFieldDidChange), name: .UITextFieldTextDidChange, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
#objc fileprivate func textFieldDidChange() {
if let number = Double(textField.text ?? "") {
textField.text = number.formattedWithDots
}
}
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
}
}
I have created a calculator and have created a Model.swift to handle all of my calculations. Then everything else is handled in my ViewController.swift. I'm trying to add another functionality, I am looking to create a history of all the operations performed in my calculator i have made and store them in an array.
Here is my code so far:
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var displayLabel: UILabel!
#IBOutlet weak var HistoryLabel: UILabel!
var historyArray: [String] = []
var userIsTypingNumbers = false
var firstNumber = 0
var secondNumber = 0
#IBAction private func NumbersEntered(_ sender: UIButton) {
//know what number is being pressed
/*let digit = sender.currentTitle!
//if user is typing a number, do this.
if userIsTypingNumbers{
//specify what number is being pressed
let textCurrentDisplay = displayLabel.text!
//append the another number onto the previous number.
displayLabel.text = textCurrentDisplay + digit
} else {
displayLabel.text = digit
}
userIsTypingNumbers = true*/
/*addToHistory(recordToAddToHistory: digit)*/
let number = sender.currentTitle
if userIsTypingNumbers {
displayLabel.text = displayLabel.text! + number!
} else {
displayLabel.text = number
userIsTypingNumbers = true
}
}
var displayValue: Double {
get {
return Double(displayLabel.text!)!
}
set {
displayLabel.text = String(newValue)
}
}
private var calculations = PerformCalculations()
#IBAction func Enter(_ sender: UIButton) {
//perform the calculations
if userIsTypingNumbers{
calculations.setOperand(operand: displayValue)
userIsTypingNumbers = false
}
if let mathematicalSymbol = sender.currentTitle {
calculations.performOperation(symbol: mathematicalSymbol)
/*addToHistory(recordToAddToHistory: String(mathematicalSymbol))*/
}
/*HistoryLabel.text = HistoryLabel.text! + String(sender.currentTitle!)*/
displayValue = calculations.result
/*HistoryLabel.text = HistoryLabel.text! + String(displayValue)*/
/*historyArray.append("\(String(describing: HistoryLabel.text))")*/
}
#IBAction func Clear(_ sender: UIButton) {
//clear display to 0.
displayLabel.text = "0"
HistoryLabel.text = ""
}
#IBAction func Delete(_ sender: UIButton) {
//deleting last typed number, if user messed up.
let name: String = self.displayLabel.text!
//count number of characters.
let stringLength = name.characters.count
let substringIndex = stringLength - 1
displayLabel.text = (name as NSString).substring(to: substringIndex)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "History"){
if let destinationVC = segue.destination as? HistoryClassViewController{
destinationVC.someData = HistoryLabel.text
}
}
}*/
}
Model.swift
import Foundation
enum Optional<T>{
case None
case Some(T)
}
class PerformCalculations {
private var accumulator = 0.0
func setOperand(operand: Double){
accumulator = operand
}
//performing the operations for various operands
private var operations: Dictionary<String, Operation> = [
"√" : Operation.UnaryOperation(sqrt), //sqrt,
"×": Operation.BinaryOperation({$0 * $1}),
"+": Operation.BinaryOperation({$0 + $1}),
"-": Operation.BinaryOperation({$0 - $1}),
"÷": Operation.BinaryOperation({$0 / $1}),
"=": Operation.Equals
]
//case for various operands
private enum Operation{
case Constant(Double)
case UnaryOperation((Double) -> Double)
case BinaryOperation((Double, Double) -> Double)
case Equals
}
//switch case to actually perform the operations
func performOperation(symbol: String){
if let operation = operations[symbol]{
switch operation{
case .Constant(let value): accumulator = value
case .BinaryOperation(let function):
executePendingBinaryOperation()
pendingVar = PendingBianryOperationInfo(binaryFunction: function, firstOperand: accumulator)
case .UnaryOperation(let foo): accumulator = foo(accumulator)
case .Equals:
executePendingBinaryOperation()
}
}
}
private func executePendingBinaryOperation(){
if pendingVar != nil{
accumulator = pendingVar!.binaryFunction(pendingVar!.firstOperand,accumulator)
pendingVar = nil
}
}
private var pendingVar: PendingBianryOperationInfo?
private struct PendingBianryOperationInfo{
var binaryFunction: (Double, Double) -> Double
var firstOperand: Double
}
var result: Double{
get{
return accumulator
}
}
}
Any help would be appreciated, thank you very much!
I have solved my problem. Here is the updated code, incase it ever comes in handy for someone.
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var displayLabel: UILabel!
#IBOutlet weak var HistoryLabel: UILabel!
var historyArray: [String] = []
var userIsTypingNumbers = false
var firstNumber = 0
var secondNumber = 0
var operation = ""
var result = 0.0
#IBAction private func NumbersEntered(_ sender: UIButton) {
//know what number is being pressed
let number = sender.currentTitle
//if user is typing number, do this.
if userIsTypingNumbers {
//specify what number is being pressed.
//append the number onto the previous number.
displayLabel.text = displayLabel.text! + number!
} else {
displayLabel.text = number
userIsTypingNumbers = true
}
}
var displayValue: Double {
get {
return Double(displayLabel.text!)!
}
set {
displayLabel.text = String(newValue)
}
}
private var calculations = PerformCalculations()
#IBAction func OperationsPressed(_ sender: UIButton) {
userIsTypingNumbers = false
firstNumber = Int(Double(displayLabel.text!)!)
operation = sender.currentTitle!
if operation == "√" {
result = (PerformCalculations().squareroot(a: Double(firstNumber)))
displayLabel.text = String(result)
}
}
#IBAction func Enter(_ sender: UIButton) {
userIsTypingNumbers = false
secondNumber = Int(Double(displayLabel.text!)!)
if operation == "+" {
result = (PerformCalculations().add(a: Double(firstNumber), b: Double(secondNumber)))
} else if operation == "÷" {
result = (PerformCalculations().division(a: Double(firstNumber), b: Double(secondNumber)))
} else if operation == "×" {
result = (PerformCalculations().multiplication(a: Double(firstNumber), b: Double(secondNumber)))
} else if operation == "-" {
result = (PerformCalculations().subtract(a: Double(firstNumber), b: Double(secondNumber)))
}
displayLabel.text = String(result)
historyArray.append("\(firstNumber) \(operation) \(secondNumber) = \(result)")
userIsTypingNumbers = false
//self.performSegue(withIdentifier: "History", sender: self)
}
#IBAction func Clear(_ sender: UIButton) {
//clear display to 0.
displayLabel.text = "0"
}
#IBAction func Delete(_ sender: UIButton) {
//deleting last typed number, if user messed up.
let name: String = self.displayLabel.text!
//count number of characters.
let stringLength = name.characters.count
let substringIndex = stringLength - 1
displayLabel.text = (name as NSString).substring(to: substringIndex)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "History" {
if let destinationVC = segue.destination as? TableTableViewController {
destinationVC.dataString = historyArray.description
}
}
}*/
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destViewController : TableTableViewController = segue.destination as! TableTableViewController
destViewController.dataString = historyArray.description
}
}
Model.swift
import Foundation
class PerformCalculations {
func add(a: Double, b: Double) -> Double {
let result = a + b
return result
}
func division(a: Double, b: Double) -> Double {
let result = a / b
return result
}
func subtract(a: Double, b: Double) -> Double {
let result = a - b
return result
}
func multiplication(a: Double, b: Double) -> Double {
let result = a * b
return result
}
func squareroot(a: Double) -> Double {
let result = sqrt(a)
return result
}
}
I got an "Class "View controller" has no initializers" error.
I tried to initialize all variables but the error keeps appearing.
Hear is the code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Screen: UILabel!
var primerNum = Float()
var segundoNum = Float()
var result = Float()
var operat = ""
var isTypingNumber = false
var num: Int?
var coma: Int?
#IBAction func num(sender: AnyObject) {
var num = sender.currentTitle
if isTypingNumber == true {
Screen.text = Screen.text! + num!!
} else {
Screen.text = num
}
isTypingNumber = true
}
#IBAction func coma(sender: AnyObject) {
var coma = sender.currentTitle
Screen.text = Screen.text! + coma!!
}
#IBAction func operat(sender: AnyObject) {
operat = sender.currentTitle!!
primerNum = (Screen.text! as NSString).floatValue
}
#IBAction func igual(sender: AnyObject) {
segundoNum = (Screen.text! as NSString).floatValue
if operat == "+" {
result = primerNum + segundoNum
} else if operat == "-" {
result = primerNum - segundoNum
} else if operat == "x" {
result = primerNum * segundoNum
} else if operat == "/" {
result = primerNum / segundoNum
} else if operat == "%" {
result = (primerNum * segundoNum) / 100
}
Screen.text = "\(result)"
}
#IBAction func clear(sender: AnyObject) {
primerNum = 0
segundoNum = 0
result = 0
Screen.text = "\(result)"
}
}
Thank you in advance!!
That looks correct, and also compiles fine for me locally. Did you try Cleaning and rebuilding (command-shift-K, then command-b)? Alternatively, restart Xcode.
I am following the Stanford iOS Swift development course and have to make my displayValue an optional double, I assign a value to displayValue func performOperation but the getter for var displayValue: Double? reads it as nil, I have even hardcoded var displayValue: Double? to be 81 (example) but it is still read as nil, has anyone got any ideas? (I didn't want to post my whole code but if I've missed something out let me know!), thanks!
EDIT: here is my whole code now!
import UIKit
class ViewController: UIViewController {
var isThereApoint = true
var openStack = Array<Double?>()
var count = 0
#IBOutlet weak var history: UILabel!
#IBOutlet weak var calcView: UILabel!
var historyStack = Array<String>()
var userIsTyping = false
#IBAction func numberButton(sender: UIButton) {
let numberButton = sender.currentTitle!
if calcView.text!.rangeOfString("=") != nil{
calcView.text! = ""
}
if userIsTyping{
calcView.text! = calcView.text! + numberButton
}
else {
calcView.text! = numberButton
userIsTyping = true
}
}
#IBAction func decimalPoint(sender: AnyObject) {
if isThereApoint == true {
calcView.text! = calcView.text! + "."
isThereApoint = false
}
}
var displayValue: Double? {
get{
if NSNumberFormatter().numberFromString(calcView.text!) != nil{
return NSNumberFormatter().numberFromString(calcView.text!)!.doubleValue
}
else {
println("calc view in getter: \(calcView.text!)")
return 0
}
}
set{
calcView.text! = "\(newValue)"
userIsTyping = false
}
}
#IBAction func operate(sender: UIButton) {
let operation = sender.currentTitle!
switch operation{
case "×": performOperation ("×, ", {$0 * $1})
case "÷": performOperation ("÷, ",{$1 / $0})
case "+": performOperation ("+, ", {$0 + $1})
case "−": performOperation ("−, ", {$1 - $0})
case "√": performOperation ("√, ", {sqrt($0)})
case "Cos": performOperation ("Cos, ", {cos($0)})
case "Sin": performOperation("Sin, ", {sin($0)})
case "PI": displayValue! = M_PI
enter()
default: break
}
}
func performOperation(operatorSymbol: String, operation: (Double, Double) -> Double) {
if openStack.count >= 2 {
println("\(operatorSymbol)")
displayValue = operation(openStack.removeLast()!, openStack.removeLast()!)
println("display value : \(displayValue!)")
var displayAnswer = displayValue!
history.text! = history.text! + operatorSymbol
calcView.text! = "= \(displayAnswer)"
enter()
//calcView.text! = "= \(displayAnswer)"
}
}
#IBAction func positiveOrNegative(sender: AnyObject) {
if (calcView.text!.rangeOfString("-") != nil) {
calcView.text! = dropFirst(calcView.text!)
}
else {
calcView.text! = "-\(calcView.text!)"
}
}
func performOperation(operatorSymbol: String, operation: Double -> Double) {
if openStack.count >= 1 {
displayValue = operation(openStack.removeLast()!)
var displayAnswer = displayValue!
history.text! = history.text! + operatorSymbol
enter()
calcView.text! = "= \(displayAnswer)"
}
}
#IBAction func clearButton() {
history.text! = ""
for item in openStack{
openStack.removeLast()
}
calcView.text! = ""
}
#IBAction func backspace(sender: AnyObject) {
if countElements(calcView.text!) > 0 {
calcView.text! = dropLast(calcView.text!)
}
}
#IBAction func enter() {
isThereApoint = true
if history.text! == "History"{
history.text! = ""
}
openStack.append(displayValue!)
var userIsTyping = false
println("openStack = \(openStack)")
history.text! = history.text! + "\(displayValue!)" + ", "
calcView.text! = ""
}
}
Your problem is that you are setting calcView.text to "Optional(81.0)". You need to unwrap the Double? that is in newValue inside of set for displayValue:
set {
calcView.text = "\(newValue!)"
userIsTyping = false
}
Because the displayValue was "Optional(81.0)", NSNumberFormatter couldn't convert the value, so it returns nil.