How to make calculator calculate in decimal form - ios

Here's my code for my calculator and it works fine!
import UIKit
class ViewController: UIViewController {
var number1 = 0
var number2 = 0
var operation = 0
#IBOutlet var screen: UILabel!
#IBAction func Onebutton(sender: AnyObject) {
addNumber(1)
}
#IBAction func Twobutton(sender: AnyObject) {
addNumber(2)
}
#IBAction func Threebutton(sender: AnyObject) {
addNumber(3)
}
#IBAction func Fourbutton(sender: AnyObject) {
addNumber(4)
}
#IBAction func Fivebutton(sender: AnyObject) {
addNumber(5)
}
#IBAction func Sixbutton(sender: AnyObject) {
addNumber(6)
}
#IBAction func Sevenbutton(sender: AnyObject) {
addNumber(7)
}
#IBAction func Eightbutton(sender: AnyObject) {
addNumber(8)
}
#IBAction func Ninebutton(sender: AnyObject) {
addNumber(9)
}
#IBAction func Zerobutton(sender: AnyObject) {
addNumber(0)
}
#IBAction func Multiplybutton(sender: AnyObject) {
operation = 1
}
#IBAction func Dividebutton(sender: AnyObject) {
operation = 2
}
#IBAction func Addbutton(sender: AnyObject) {
operation = 3
}
#IBAction func Subtractbutton(sender: AnyObject) {
operation = 4
}
#IBAction func Equalsbutton(sender: AnyObject) {
switch operation{
case 1: screen.text = String (number1*number2)
case 2: screen.text = String (number1/number2)
case 3: screen.text = String (number1+number2)
case 4: screen.text = String (number1-number2)
default: println()
}
}
#IBAction func clearbutton(sender: AnyObject) {
number1 = 0
number2 = 0
operation = 0
screen.text = "0"
}
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.
}
func addNumber (pushButton : Int){
if operation == 0 {
number1 = number1*10+pushButton
screen.text = String (number1)
} else {
number2 = number2*10+pushButton
screen.text = String (number2)
}
}
}
But I want to make the calculator calculate in decimal form and not round off to the nearest number.

Use floats.
var number: Float = 0
number = number + 0.1
println(number)
//0.1 should be printed.
You are currently basically saying:
var number: Int = 0
This is pretty much how the computer reads it; number is an integer. To make it so that number can be a decimal (float), you have to say:
var number: Float = 0

Related

How do I store data (user input from a textfield)

I am using Swift and I want to know how I can store user input as a variable (it’s a double).
I'm still in the learning states so I have been watching youtube tutorials on the situation but nothing helped.
My code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var userInput: UITextField!
override func viewDidLoad() {
userInput.delegate = self
}
#IBAction func Increment(_ sender: UIButton) {
var inc = 0
userInput = userInput + inc
}
#IBAction func Decrement(_ sender: UIButton) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
userInput.resignFirstResponder()
}
}
extension ViewController: UITextFieldDelegate{
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
The user will be able to enter a number and increment or decrement the number by a certain input value.
//fetch any number from textfield
func getValueFromTextfield() -> Double?{
guard let text = userInput.text else {
print("Missing user input")
return nil
}
guard let doubleValue = Double(text) else {
print("parse failure")
return nil
}
return doubleValue
}
// Now for increment and decrement we have methods be like, Am assuming certain input value as 1 to be used for increment and decrement replace this if needed
func increment(){
// get value
if let value = getValueFromTextfield(){
userInput.text = “\(value + 1)” // increment by 1
}
}
func decrement(){
// get value and check if it’s greater than zero
if let value = getValueFromTextfield(), value > 0{
userInput.text = “\(value - 1)” // decrement by 1
}
}
#IBAction func Increment(_ sender: UIButton) {
increment()
}
#IBAction func Decrement(_ sender: UIButton) {
decrement()
}
These method will help you achieve increment or decrement operation without need to store value in any variable.
If you still want to save value in variable just simply store value returned from method let valueToStore = getValueFromTextfield()
Your code won't compile correctly but the answer to your question is:
let doubleValue = Double(userInput.text!)! converts your code to double
or better using optional unwrapping:
guard let text = userInput.text else {
print("text of userInput is nil")
return
}
guard let doubleValue = Double(text) else {
print("Impossible to parse \(text) into Double")
return
}
print(doubleValue)
#IBAction func Increment(_ sender: UIButton) {
if let text = userInput.text, var doubleText = Double(text) {
doubleText = doubleText + 1
userInput.text = "\(doubleText)"
}
}
Similarly you can write for Decrement.
#IBAction func Increment(_ sender: UIButton) {
var inc = 0
userInput.text = ( Double(userInput.text) + Double(inc) ).rounded(toPlaces: 1)
}

How to randomly print a word in an iOS app?

I have been trying to create an app that randomly prints a new word after a certain amount of time, i.e five seconds.
import UIKit
class ViewController: UIViewController {
var myTimer : Timer!
var theValue = 0
#IBOutlet weak var textLabel: UILabel!
#IBOutlet weak var InspireLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib
}
override func viewDidDisappear(_ animated: Bool) {
self.myTimer.invalidate()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#objc func updateMyLabel() {
theValue += 1
self.textLabel.text = String(theValue)
}
func randomText() -> String {
if theValue > 5 {
let words = ["Place", "Cat", "House"]
return words.randomElement() ?? "" //Use default method to get random element from Array
}
return "string if theValue < 5 or equal to 5"
}
#IBAction func ResetButton(_ sender: Any) {
self.myTimer.invalidate()
theValue = 0
self.textLabel.text = String(theValue)
}
#IBAction func PauseButton(_ sender: Any) {
self.myTimer.invalidate()
}
#IBAction func PlayButton(_ sender: Any) {
self.myTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateMyLabel), userInfo: nil, repeats: true)
}
}
This is all the code I have right now. As you can probably tell I'm new too StackExchange and so please excuse any breach in etiquette.
it's giving an error because you forgot to add else part in your code.
func randomText() -> String {
if theValue > 5 {
let words = ["Place", "Cat", "House"]
return words.randomElement() ?? "" //Use default method to get random element from Array
}
return "string if theValue < 5 or equal to 5"
}

Cannot receive event with custom DelegateProxy and Protocol

I try to migrate delegate of DifficultyViewDelegate to observable. This is my DifficultyViewDelegate :
#objc protocol DifficultyViewDelegate: class {
func levelDidIncrease()
func levelDidDecrease()
}
And my DifficultyView :
weak var delegate: DifficultyViewDelegate?
#IBAction func decreaseLevel(_ sender: Any) {
delegate?.levelDidDecrease()
}
#IBAction func increaseLevel(_ sender: Any) {
delegate?.levelDidIncrease()
}
And this is my RxDifficultyViewDelegateProxy
class RxDifficultyViewDelegateProxy: DelegateProxy, DelegateProxyType {
static func currentDelegateFor(_ object: AnyObject) -> AnyObject? {
let difficultyView: DifficultyView = object as! DifficultyView
return difficultyView.delegate
}
static func setCurrentDelegate(_ delegate: AnyObject?, toObject object: AnyObject) {
let difficultyView: DifficultyView = object as! DifficultyView
difficultyView.delegate = delegate as? DifficultyViewDelegate
}
}
I also added an extension on my DifficultyView :
extension DifficultyView {
public var rx_delegate: RxDifficultyViewDelegateProxy {
return RxDifficultyViewDelegateProxy.proxyForObject(RxDifficultyViewDelegateProxy.self)
}
public var rx_levelDidIncrease: Observable<Void> {
return rx_delegate.methodInvoked(#selector(DifficultyViewDelegate.levelDidIncrease)).map { _ in return }
}
}
But it seems that when I do :
difficultyView.rx_levelDidIncrease.asObservable().subscribe(onNext: {
print("did increase")
}).addDisposableTo(disposeBag)
It's never called. Someone has any pointers ?
Try use PublishSubject:
DifficultyView:
class DifficultyView: UIView {
var levelDidIncrease = PublishSubject<Void>()
var levelDidDecrease = PublishSubject<Void>()
#IBAction func decreaseLevel(_ sender: Any) {
levelDidDecrease.onNext()
}
#IBAction func increaseLevel(_ sender: Any) {
levelDidIncrease.onNext()
}
}
And then:
var difficultyView = DifficultyView()
difficultyView.levelDidDecrease.asObservable()
.subscribe(onNext: {
print("did decrease")
})
.addDisposableTo(disposeBag)
difficultyView.decreaseLevel(theSender) // <- THIS line performs the side effect

UIButton inside UISegmentedControl action

I am continuing my calculation program to improve my skills in Swift code. Right now I have a problem: I want that an UISegmentedControl select the operator of my operations (+, - ecc..) and when one is selected a UIButton func calculate the values based on the decision of the UISegmentedControl.
Here is the code but is not working.
Thanks,
Matteo
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var firstNumber: UITextField!
#IBOutlet weak var secondNumber: UITextField!
#IBOutlet weak var resultButton: UIButton!
#IBOutlet weak var resultNumber: UILabel!
#IBOutlet weak var operatorSelector: UISegmentedControl!
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.
}
#IBAction func operatorSelectorChanged(_ sender: UISegmentedControl) {
switch operatorSelector.selectedSegmentIndex {
case 0:
#IBAction func resultFunction(_ sender: AnyObject) {
if let firstNumberConv :Int = Int(firstNumber.text!), let secondNumberConv :Int = Int(secondNumber.text!) {
let result = firstNumberConv + secondNumberConv
resultNumber.text = "\(result)"
} else { resultNumber.text = "Inserire solo valori numerici"}
}
case 1:
#IBAction func resultFunction(_ sender: AnyObject) {
if let firstNumberConv :Int = Int(firstNumber.text!), let secondNumberConv :Int = Int(secondNumber.text!) {
let result = firstNumberConv - secondNumberConv
resultNumber.text = "\(result)"
} else { resultNumber.text = "Inserire solo valori numerici"}
}
default:
break;
}
}
}
Try removing the lines with #IBAction func ... inside your switch cases.
I think your #IBAction func operatorSelectorChanged should look something like this:
#IBAction func operatorSelectorChanged(_ sender: UISegmentedControl) {
switch operatorSelector.selectedSegmentIndex {
case 0:
if let firstNumberConv = Int(firstNumber.text!), let secondNumberConv = Int(secondNumber.text!) {
let result = firstNumberConv + secondNumberConv
resultNumber.text = "\(result)"
} else { resultNumber.text = "Inserire solo valori numerici"}
case 1:
if let firstNumberConv = Int(firstNumber.text!), let secondNumberConv = Int(secondNumber.text!) {
let result = firstNumberConv - secondNumberConv
resultNumber.text = "\(result)"
} else { resultNumber.text = "Inserire solo valori numerici"}
default:
break;
}
}
A possible solution for your problem is to define an IBAction that calculates the result of adding/subtracting two numbers
#IBAction func calculate(_ sender: AnyObject) {
if let a = Int(firstNumber.text!), let b = IntsecondNumber.text!) {
switch operatorSelector.selectedSegmentIndex {
case 0:
resultNumber.text = "\(a+b)"
case 1:
resultNumber.text = "\(a-b)"
default:
print("❗️unknown operator selected")
}
}
}
You could then bind this action to the sent events from your user interface: for example the Editing Changed event of your text fields (firstNumber and secondNumber) and the Value Changed of your segmented control (operatorSelector)
I created an example project that illustrates this: https://github.com/dev1an/calculator
How to bind multiple events to one IBAction
Write down the IBAction in code (like the calculate action I wrote above). Go to your storyboard and open the assistent editor (AltCmdEnter). Select a UI element (like a text field) in the interface builder. Open the Connections Inspector (AltCmd6) and drag from the circle next to a sent event (for example Editing Changed) to your IBAction code.

How do I access a variable in a button action in Swift

I cannot access the variable incomeValue in the savingsGoal function. Xcode gives me the error "Use of unresolved identifier 'incomeValue'.
#IBAction func incomeSliderChanged(sender: UISlider) {
var incomeValue = Double(sender.value)
currentIncomeLabel.text = ("$\(incomeValue) /yr")
}
#IBAction func savingsSliderChanged(sender: UISlider) {
var savingsValue = Int(sender.value)
savingsLabel.text = ("\(savingsValue)% of income")
println("savings value \(savingsValue)%")
}
#IBAction func indexChanged(sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
println("first segement clicked")
case 1:
println("second segment clicked")
default:
break;
}
}
#IBAction func calculateButtonPressed(sender: AnyObject) {
}
func savingsGoal () {
var futureIncome = incomeValue + (incomeValue * 3.8)
}
}
Your problem is that you declared incomeValue inside your incomeSliderChanged(_:) function. This limits the scope of incomeValue to that function, meaning you can only reference it from withing the opening { and closing } of incomeSliderChange(_:). To fix this declare your incomeValue variable outside of the function.
var incomeValue: Double = 0.0 // You can replace 0.0 with the default value of your slider
#IBAction func incomeSliderChanged(sender: UISlider) {
// Make sure you get rid of the var keyword.
// The use of var inside this function would create a
// second incomeValue variable with its scope limited to this function
// (if you were to do this you could reference the other incomeValue
// variable with self.incomeValue).
incomeValue = Double(sender.value)
currentIncomeLabel.text = ("$\(incomeValue) /yr")
}
func savingsGoal() {
// You can now access incomeValue within your savingsGoal() function
var futureIncome = incomeValue + (incomeValue * 3.8)
}
If you are new to programming, I recommend reading about the concept of Scope: http://en.wikipedia.org/wiki/Scope_(computer_science)

Resources