Why won't swift recalculate the 'if' statement? - swift

I'm trying to create a very simple 'guessing game' where the user has to guess how many fingers the computer has up (maximum 5 fingers).
Here's the thing. When the code executes and I press submit, even when the print logs registers a correct number, the app still prints the if statement for incorrect. Where am I going wrong?
import UIKit
class ViewController: UIViewController {
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.
}
#IBOutlet weak var fingerInput: UITextField!
#IBOutlet weak var fingerResult: UILabel!
#IBAction func fingerSubmit(sender: AnyObject) {
let realNumberofFingers = Int(arc4random_uniform(6))
print(realNumberofFingers)
if fingerInput != realNumberofFingers {
fingerResult.text = "Gosh darn, that's wrong!"
} else if fingerInput == realNumberofFingers {
fingerResult.text = "Thats right!"
}
}
}

You are comparing the actual UITextField fingerInput with the realNumberofFingers. That is wrong and will always yield false. What you should do instead is parse the string from the fingerInput and check if the integer contained in that string is equal to realNumberofFingers:
#IBAction func fingerSubmit(sender: AnyObject) {
let input = Int(fingerInput.text!)
if let enteredFingers = input {
let realNumberofFingers = Int(arc4random_uniform(6))
print(realNumberofFingers)
if enteredFingers == realNumberofFingers {
fingerResult.text = "Thats right!"
} else {
fingerResult.text = "Gosh darn, that's wrong!"
}
} else {
fingerResult.text = "Please enter a correct guess - an integer!"
}
}

Related

Swift error when I press button more times than there are pizzas in my array list

So I just started programming and I am now getting this error.
It occurs every time I press the button more times than there are Pizzas in the list.
Full error code: Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0):
Here`s my code so far:
import UIKit
var pizzaNumber = 0
var pizzaNames = ["Skinke Pizza", "Salat Pizza", "Pepperoni Pizza"]
let priser = [65,70,65]
var totalProdukt = pizzaNames.count
class ViewController: UIViewController {
#IBOutlet weak var produktNavn: UILabel!
#IBAction func rightButton(_ sender: UIButton) {
pizzaNumber+=1
showPizza()
}
#IBAction func leftButton(_ sender: UIButton) {
pizzaNumber-=1
if pizzaNumber < 0 {
pizzaNumber = 0
}
showPizza()
}
func showPizza() {
if pizzaNumber > totalProdukt {
pizzaNumber = pizzaNames.count
} else {
self.produktNavn.text = pizzaNames[pizzaNumber]
}
}
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.
}
}
You should make sure that pizzaNumber-1 can never be bigger than the number of elements in your array to ensure that you are never trying to access an index that doesn't exist. This can be easily done by changing totalProdukt to be a computed variable. This way, the value of the variable will always be updated when you are trying to access it.
var totalProdukt: Int {
return pizzaNames.count
}
Also bear in mind that array indexing starts at 0, so you need
if pizzaNumber >= totalProdukt {
pizzaNumber = pizzaNames.count-1
} else {
self.produktNavn.text = pizzaNames[pizzaNumber]
}
Bear in mind that with your current code, there's no need for storing the count of the array in a separate variable, since you are only using it at one place in code.
Moreover, the cleanest solution is to check the value before actually increasing it rather than when using it, this way in showPizzas you don't need to do any checks, just update the label:
class ViewController: UIViewController {
#IBOutlet weak var produktNavn: UILabel!
#IBAction func rightButton(_ sender: UIButton) {
if pizzaNumber < pizzas.count-1 {
pizzaNumber+=1
}
showPizza()
}
#IBAction func leftButton(_ sender: UIButton) {
if pizzaNumber > 0 {
pizzaNumber-=1
}
showPizza()
}
func showPizza() {
self.produktNavn.text = pizzaNames[pizzaNumber]
}
}
Here's how to fix your error
func showPizza() {
if pizzaNumber >= totalProdukt { // << Added '=' since pizzaNames[pizzaNames.count] is out of bounds
pizzaNumber = pizzaNames.count - 1
} else {
self.produktNavn.text = pizzaNames[pizzaNumber]
}
}

Class 'ViewController' has no initializers - Similar questions couldn't resolve issue

I have searched for similar questions, but they could not resolve my issue, so I hope it's ok, that I am asking it again. Here is my code:
import UIKit
class ViewController: UIViewController {
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.
}
#IBOutlet weak var revealLabel: UILabel!
#IBOutlet weak var scoreLabel: UILabel!
#IBOutlet weak var textField: UITextField!
var userGuess: Int
var heldUpFingers: Int
var score: Int = 0
#IBAction func startGame(sender: UIButton) {
userGuess = Int(textField.text!)!
if textField.text == nil {
revealLabel.text = "Please enter a number from 1 to 5"
} else if userGuess > 5 {
revealLabel.text = "Please enter a number from 1 to 5"
} else {
heldUpFingers = Int(arc4random_uniform(5) + 1)
if heldUpFingers == userGuess {
revealLabel.text = "You guessed right!"
score += 1
scoreLabel.text = String(score)
} else {
revealLabel.text = "Wrong, it was \(heldUpFingers)"
}
}
}
}
It gives me the error "Class 'ViewController' has no initializers" in the 3rd line. Thanks in advance!
It is because userGuess and heldUpFingers aren't assigned yet. You can either make these optional by adding a ? after the Int or by setting a default value to them. So either:
var userGuess: Int?
var heldUpFingers: Int?
You will then need to unwrap them/check there not nil later in your code like this:
if userGuess != nil {
//now safely use userGuess!
}
Or
var userGuess: Int = 0
var heldUpFingers: Int = 0

In Swift how do I convert int to string and reverse and display result?

The program is suppose to change F TO C and reverse. With the Switch it changes from on to off and on is suppose to be C to f and off is F to c and entering the # underneath in the text field.
When clicking the submit button it takes whats in the text field transfers it to an in preforms the algorithm and then displays it in the textfield.
I believe the conversion is going correctly but will not display the actual result. Or the way its being converted is wrong.
#IBOutlet weak var buttonClicked: UIButton!
#IBOutlet weak var mySwitch: UISwitch!
#IBOutlet weak var myTextField: UITextField!
#IBOutlet weak var User: UITextField!
func stateChanged(switchState: UISwitch) {
if switchState.on {
myTextField.text = "Convert to Celius"
} else {
myTextField.text = "Convert to Farheniet"
}
}
#IBAction func buttonClicked(sender: UIButton) {
if mySwitch.on {
var a:Double? = Double(User.text!)
a = a! * 9.5 + 32
User.text=String(a)
mySwitch.setOn(false, animated:true)
} else {
var a:Double? = Double(User.text!)
a = a! * 9.5 + 32
User.text=String(a)
mySwitch.setOn(true, animated:true)
}
}
I am using an older version of XCode(6.4) so my code will be a little bit different from yours. From what I understand your function buttonClicked should take the argument of AnyObject instend of UIButton. Also you do not call the function stateChanged in your code at all. The following code should help achieve what you trying to do.
#IBOutlet weak var mySwitch: UISwitch!
#IBOutlet weak var myTextField: UITextField!
#IBOutlet weak var User: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// sets the textfield to the intended conversion on load.
if mySwitch.on {
myTextField.text = "Convert to Celius"
}
else {
myTextField.text = "Convert to Farheniet"
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// changes the myTextFiled text to the intended conversion when the switch is manually switched on or off
#IBAction func switched(sender: AnyObject) {
if mySwitch.on {
myTextField.text = "Convert to Celsius"
}
else {
myTextField.text = "Convert to Fahrenheit"
}
}
// changes the myTextField text to intended reverse conversion after the buttonClicked func is completed.
func stateChanged(switchState: UISwitch) {
if switchState.on {
myTextField.text = "Convert to Celsius"
}
else {
myTextField.text = "Convert to Fahrenheit"
}
}
// do the intended conversion(old version of XCode 6.4)
#IBAction func buttonClicked(sender: AnyObject) {
if mySwitch.on {
var a = (User.text! as NSString).doubleValue
a = (a-32)*(5/9)
User.text="\(a)"
mySwitch.setOn(false, animated:true)
stateChanged(mySwitch)
}
else {
var a = (User.text! as NSString).doubleValue
a = a * (9/5) + 32
User.text="\(a)"
mySwitch.setOn(true, animated:true)
stateChanged(mySwitch)
}
}

Swifit (my first program) catching user input

I can't figure out how the value of a.sucess and a.attempt will come from the input of the user writing numbers in the success and attempt box.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Attempts: UITextField!
#IBOutlet weak var Sucess: UITextField!
#IBOutlet weak var Check: UIButton!
#IBOutlet weak var thepage: UILabel!
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 Check(sender: UIButton) {
var str = "here"
class Tries {
var Attempts:Float64 = 100.00
var Sucess:Float64 = 50.00
init() {
}
func Shot() {
if Attempts < 99.5 {
print ("you need more attempts :( Shoot some more!!")
}
else if Attempts > 99 && Sucess > 49 && Sucess / Attempts > 0.4999
{
print("accepted")
} else {
print("failed ")
}
}
}
var a = Tries()
a.Attempts = 200 // this input should come from the user writing input in the textfield... (NEED HELP HERE)
a.Sucess = 100 // this input should come from the user writing input in the textfield... (NEED HELP HERE)
a.Shot() // This is the function that should load when you click on the button: click
}
I want a.Attempts and a.Sucess to get the value from the user writing his/Her own numbers in the two boxes.
First of all you have a very bad style of writing code. What you wrote is very difficult to read. Call variables clearer and do not call objects with a capital letter, it need call the names indicate the type and not the names of the objects. Reed this for example: https://github.com/raywenderlich/swift-style-guide to make your code more clear.
About you problem. Maybe I did not quite understand the question, but apparently you just have to read the value of the UITextField object and you can do it like:
let strValue = textField.text // in your case Attempts.text
then you need to convert it to CGFloat:
let floatValue = CGFloat((strValue as NSString).floatValue)
and then you can use it in your object:
a.Attempts = floatValue
You should still check that the conversion went well and only then assign a value.
You can do this for example to solve you problem:
import UIKit
class ValuesChecker {
class func checkValues(firstValue: Float, secondValue: Float) -> String {
if firstValue < 99.5 {
return "you need more attempts :( Shoot some more!!"
} else if firstValue > 99 && secondValue > 49 && secondValue / firstValue > 0.4999 {
return "accepted"
} else {
return "failed "
}
}
}
class ViewController: UIViewController {
#IBOutlet weak var firstTextField: UITextField!
#IBOutlet weak var secondTextField: UITextField!
#IBAction func actionWithPressButton(sender: AnyObject) {
let firstValue = (firstTextField.text as NSString).floatValue
let secondValue = (secondTextField.text as NSString).floatValue
println(ValuesChecker.checkValues(firstValue, secondValue: secondValue))
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Comments:
You dont need to create class object in your case. You can create static class method like checkValues
Instead of a String you can give out test results in any way, and use it later in the program

nill error when trying to concatenate a string

I followed a tutorial and did everything correct. I can print out the age in the console just when I try to set the labels text I get a nil error.
class ViewController: UIViewController {
#IBOutlet var inputField: UITextField!
#IBOutlet var outputLbl: UILabel!
#IBAction func enterBtn(sender: AnyObject) {
if(inputField != nil){
var age = inputField.text.toInt()
println(age)
var catYears = age! * 7
println(catYears)
outputLbl.text = "Your cat is \(catYears) old"
}
else {
outputLbl.text = "Please enter a age"
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I read the documentation and I'm concatenating the string correctly. However like I said, when I take the follow statement out:
outputLbl.text = "Your cat is \(catYears) old"
the program run fine.
I would recommend refactoring this to check whether the entered text is able to be converted into an int. You should not check whether the textField != nil since is will not be nil if the storyboard loaded properly.
Consider this change:
#IBAction func enterBtn(sender: UIButton) {
if let age = inputField.text.toInt() {
println(age)
var catYears = age * 7
println(catYears)
outputLbl.text = "Your cat is \(catYears) old"
} else {
outputLbl.text = "Please enter a valid age"
}
}
Not sure why this made a difference but I deleted the label and recreated it and it worked.