I'm really new to Swift and I am having problems with the conversion of a string (entered in a text field) to an integer.
I'm trying to create a small calculation app (I was following a tutorial on YouTube but it's old).
My app has 3 text fields, a label (that is meant to display the result), and a button to start the calculation.
Here's the code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var valueA: UITextField!
#IBOutlet weak var valueB: UITextField!
#IBOutlet weak var valueC: UITextField!
#IBOutlet weak var result: UILabel!
#IBAction func calculateTotal(_ sender: Any) {
var a:Int? = Int(valueA.text)
var b:Int? = Int(valueB.text)
var c:Int? = Int(valueC.text)
var answer = a! * b! * c!
}
}
Try this (crash free code and you can add n number of textfield/string values as a number string):
var arrayOfTextFieldValues = [valueA.text, valueB.text, valueC.text]
#IBAction func calculateTotal(_ sender: Any) {
if let multiplication = multiplication(arrayString: arrayOfTextFieldValues) {
print("Answer = \(multiplication)")
result.text = "\(multiplication)"
}
}
// handle operations
func multiplication(arrayString: [String?]) -> Int? {
var answer:Int?
for arrayElement in arrayString {
if let stringValue = arrayElement, let intValue = Int(stringValue) {
answer = (answer ?? 1) * intValue
}
}
return answer
}
Related
So i recently tried to create a very simple calcylator in xcode, the problem i have is when i press the calculate button when there is no numbers there the app crashes, and when i put anything that isnt a number there and press the calculate button it also crash, and i know it crash cause it cant convert nothing/non numbers into a double, but how do i check if it is numbers in the textfields and if it is it will show the result off the
equation and if there is no number it will just set the textfeilds to nothing
(faktor1.text = "") (faktor2.text = "") ...
well it looks like this right now (ränka ut means calculate)
here is the code i used,
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var faktor1: UITextField!
#IBOutlet weak var faktor2: UITextField!
#IBOutlet weak var result: UILabel!
#IBOutlet weak var calculatebutton: UIButton!
#IBOutlet weak var clearui: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
result.text = ""
calculatebutton.layer.cornerRadius = 25.0
result.layer.cornerRadius = 25.0
clearui.layer.cornerRadius = 25.0
}
#IBAction func calculate( sender: Any) {
let input1 = Double(faktor1.text!)!
let input2 = Double(faktor2.text!)!
let calculation = input1 * input2
result.text = "(calculation)"
}
#IBAction func clearfnc( sender: Any) {
result.text = ""
faktor1.text = ""
faktor2.text = ""
}
}
You can simply unwrap your optionals the Swift way, instead of using ! (force unwrap)
This is an example using guard:
#IBAction func calculate(sender: Any) {
guard
let input1String = faktor1.text,
let input2String = faktor1.text,
let input1 = Double(input1String),
let input2 = Double(input2String)
else {
faktor1.text = ""
faktor1.text = ""
return
}
let calculation = input1 * input2
result.text = "\(calculation)"
}
Heres the code I have so far, now when a user inputs any letter, my label display nothing, what I would like to figure out is how to turn that nothing "", into a 0. I tried doing an if statement on my "label.txt ="'s but that didn't pan out. What would be a better way of finding my desired results?
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var game1: UITextField!
#IBOutlet weak var game2: UITextField!
#IBOutlet weak var game3: UITextField!
#IBOutlet weak var series: UILabel!
#IBOutlet weak var average: UILabel!
#IBOutlet weak var high: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func calculate(_ sender: Any) {
self.view.endEditing(true)
guard
let text1 = game1.text,
let text2 = game2.text,
let text3 = game3.text
else { return }
guard
let game1Results = Int(text1),
let game2Results = Int(text2),
let game3Results = Int(text3)
else { return }
let gameResultsArray = [game1Results, game2Results, game3Results]
let sumArray = gameResultsArray.reduce(0, +)
let positiveArray = gameResultsArray.filter {
(item: Int) -> Bool in return item > 0
}
var avgArrayValue = 0
if positiveArray.count == 0
{
avgArrayValue = 0
}else {
avgArrayValue = sumArray / positiveArray.count
}
series.text = "\(sumArray)"
average.text = "\(avgArrayValue)"
if let maximumVal = gameResultsArray.max() {
high.text = String(maximumVal)
}
}
}
Here is what you need, convert String to Int and give the default 0. Instead of using the guard let return use this method:
Instead of this:
guard let game1Results = Int(text1) else { return }
Use this:
let game1Results = Int(text1) ?? 0
I am trying to create an app that can help you calculate sales tax on an item. Of course the app requires multiplication But I keep encountering the error:
"Type of expression is ambiguous without more context"
Can you help me? I'm new to swift so also try to explain why I am incorrect. This is my code so far:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Item: UITextField!
#IBOutlet weak var Tax: UITextField!
#IBOutlet weak var Answer: UITextField!
#IBAction func Calculate(_ sender: Any) {
let a = Item.text
let conversionRate = Tax
let b = Int(a!)! * conversionRate
Answer.text = ("\(b)")
}
}
Thanks!!
Your primary issue is your attempt to multiply an Int and a UITextField.
You attempt to create an Int from Item.text but you make no similar attempt to convert Tax.text to a number.
There are also many other issues with your code. You are using the ! operator too much and your app will crash as a result.
And your naming conventions need to be improved. Variables and methods should start with lowercase letters.
Here's your code as it should be written:
class ViewController: UIViewController {
#IBOutlet weak var item: UITextField!
#IBOutlet weak var tax: UITextField!
#IBOutlet weak var answer: UITextField!
#IBAction func calculate(_ sender: Any) {
if let itemStr = item.text, let taxStr = tax.text, let itemVal = Int(itemStr), let taxVal = Int(taxStr) {
let result = itemVal * texVal
answer.text = "\(result)"
} else {
answer.text = "Invalid values"
}
}
}
You're trying to multiply a variable of UITextField type with a variable of Int. Try this:
class ViewController: UIViewController {
#IBOutlet weak var Item: UITextField!
#IBOutlet weak var Tax: UITextField!
#IBOutlet weak var Answer: UITextField!
#IBAction func Calculate(_ sender: Any) {
guard let a = Int(Item.text ?? "0") else { return }
guard let conversionRate = Int(Tax.text ?? "0") else { return }
let b = a * conversionRate
Answer.text = ("\(b)")
}
}
I have the user input numbers into some textFields. Then I make some combinations out of them and then do a series of finding of finding which number is greater than the other. For example out of a and b which is greater, then out of c and d which is greater. Then out of the the two winners which is greater from that. I want my ultimate answer to be displayed in a label on a different viewController, but am having trouble with this.
I created a struct called "help" in a swift file called "PrisonerModel.swift" and want the answer to be displayed in the answer label on MatrixViewController. I believe my problem is coming up something in the process of calling the answer.
My code:
import Foundation
struct PrisonerModel {
var x: String
var y: String
var z: String
var a: String
var b: String
var c: String
var d: String
var e: String
var answer: String
}
struct help {
var f: String
func greaterInt(x: Int, _ y: Int) -> Int {
if x > y {
return x}
return y
}}
Second ViewController
class MatrixViewController: UIViewController {
#IBOutlet weak var P1CoopCoop: UILabel!
#IBOutlet weak var P2CoopCoop: UILabel!
#IBOutlet weak var P1DefCoop: UILabel!
#IBOutlet weak var P2DefCoop: UILabel!
#IBOutlet weak var P1CoopDef: UILabel!
#IBOutlet weak var P2CoopDef: UILabel!
#IBOutlet weak var P1DefDef: UILabel!
#IBOutlet weak var P2DefDef: UILabel!
#IBOutlet weak var answer1: UILabel!
var labelText1 = ""
var model: PrisonerModel?
var answer: help?
override func viewDidLoad() {
super.viewDidLoad()
P1CoopCoop.text = model?.x
P2CoopCoop.text = model?.y
P1DefCoop.text = model?.z
P2DefCoop.text = model?.a
P1CoopDef.text = model?.b
P2CoopDef.text = model?.c
P1DefDef.text = model?.d
P2DefDef.text = model?.e
answer1.text = answer?.f
Segue
prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showMatrix" {
if let matrixVC = segue.destinationViewController as? MatrixViewController {
let pm = PrisonerModel(x: Text3.text ?? "", y: Text3.text ?? "", z: Text4.text ?? "", a: Text1.text ?? "", b: Text1.text ?? "", c: Text4.text ?? "", d: Text2.text ?? "", e: Text2.text ?? "", answer: String(Int(Text1.text! + Text3.text!)) ?? "")
matrixVC.model = pm
}
}
}
It isn't clear what the "answer" should be, but some general advice is to convert your text values to integers so that you can perform appropriate mathematical operations on them.
I would implement func shouldPerformSegue(withIdentifier identifier: String,
sender: Any?) -> Bool to first validate your inputs and create your model:
struct PrisonerModel {
var x: Int
var y: Int
var z: Int
var a: Int
var b: Int
var c: Int
var d: Int
var e: Int
var answer: Int
}
var model: PrisonerModel?
override func shouldPerformSegue(withIdentifier identifier: String,
sender: Any?) -> Bool {
if let identifier == "showMatrix" {
guard let a = Int(text1.text!),
let b = Int(text1.text!),
let c = Int(text4.text!),
let d = Int(text2.text!),
let e = Int(text2.text!),
let x = Int(text3.text!),
let y = Int(text3.text!),
let z = Int(text4.text!),
let answer = Int(text1.text + text3.txt) else {
// Probably set some text in a label informing the user that their input is invalid
return false
}
self.model = PrisonerModel(x:x, y:y, z:z, a:a, b:b, c:c, d:d, e:e, answer:answe)
return true
}
}
return false
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showMatrix" {
if let matrixVC = segue.destinationViewController as? MatrixViewController,
let model = self.model {
matrixVC.model = model
}
}
}
Note I have changed the name of your text field properties to start with a lower case letter as is convention. Also your code would possibly be clearer if you had better names for your model properties than a,b,c etc.
Also the use of the force unwrap for the text properties is safe unless you have explicitly assigned nil to the property; by default a UITextField will have a string assigned to text.
I want to add value of textfield. I want to check textfield is empty or not or checking other value than int. I am newer in Swift. Please help any help would be apperciated.
#IBOutlet var label :UILabel!
#IBOutlet var first : UITextField!
#IBOutlet var third : UITextField!
#IBOutlet var second : UITextField!
var bloa :NSString?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func playPressed(sender: UIButton) {
var a: Int = 0
var b: Int = 0
var c: Int = 0
var d: Int = 0
if first.text!.isEmpty || second.text!.isEmpty || third.text!.isEmpty {
return
}
else
{
// If on first textfield there is another value than int they show
//fatal error: unexpectedly found nil while unwrapping an Optional value
a = (Int)(first.text!)!
b = Int(second.text!)!
c = Int(third.text!)!
d = a + b + c
label?.text = String (format: "%d",d)
}
Try this:
if first!.text == "" || second!.text == "" || third!.text == "" {
}
You don't need to check if it is empty or not this way:
guard let a = Int((first?.text)!), b = Int((second?.text)!) , c = Int((third?.text)!) else {
print("Not convertable to Int or field are empty")
return
}
And your final code will be:
import UIKit
class ViewController: UIViewController {
#IBOutlet var label :UILabel?
#IBOutlet var first : UITextField?
#IBOutlet var third : UITextField?
#IBOutlet var second : UITextField?
override func viewDidLoad() {
playBackgroundMusic("Naughty_Boy.mp3")
}
#IBAction func playPressed(sender: UIButton) {
guard let a = Int((first?.text)!), b = Int((second?.text)!) , c = Int((third?.text)!) else {
print("Not convertable to Int or field are empty")
return
}
let d = a + b + c
label?.text = String (format: "%d",d)
}
}
If you set the keyboard for all these text boxes as below screenshot and change is marked in red rectangle. You don't need to check the given character/word is integer or not in the code.
Set your keyboard type to Number Pad from the Storyboard. then do this in code:
#IBAction func playPressed(sender: UIButton) {
if first?.text?.isEmpty || second?.text?.isEmpty || third?.text?.isEmpty {
}
}