nill error when trying to concatenate a string - swift

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.

Related

I don't know what I'm doing wrong in this Swift project?

I'm trying to program a formal system that has these rules:
You start with the string "MI" (which is the text of the label at the beginning)
There are four rules of inference :
1) If the last character of the string is "I", you can add a "U" to the string (ex: MI --> MIU)
2) Being x a sequence of letters, Mx can be replaced with Mxx (ex: MIU --> MIUIU)
3) If the string contains "III", you can replace "III" with "U" (ex: MUIII --> MUU)
4) If the string contains "UU", you can delete the "UU" part (ex: MIIUU --> MII)
In my project, rule 1 corresponds to button1, rule 2 to button2, rule 3 to button3, rule 4 to button 4
Also, since a user may end up in a infinite loop sometimes (ex: if you get to "MIU", from then on you can only use rule 2 and get "MIUIU" and so on) I added a "clear" button.
I want the clear button to just turn the Label.text into "MI" so the user can just go back to the starting point and retry
The point is, for some reason when I press the "clear" button the Label.text does not turn into "MI" as I would want it to, but it turns into "MIU" instead!
What am I missing?
PS: I know this might is probably something extremely easy that I'm stuck on, but I don't have much programming experience
This is my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Label: UILabel!
#IBOutlet weak var rule1Button: UIButton!
#IBOutlet weak var rule2Button: UIButton!
#IBOutlet weak var rule3Button: UIButton!
#IBOutlet weak var rule4Button: UIButton!
#IBOutlet weak var clearButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
clear()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var string : String = "MI"
var string1 : String = ""
func rule1() {
if string.characters.last == "I" {
string.append("U")
Label.text = string
}
}
func rule2() {
string1 = string.replacingOccurrences(of: "M", with: "")
string = string + string1
Label.text = string
}
func rule3() {
string = self.string.replacingOccurrences(of: "III", with: "U")
Label.text = string
}
func rule4() {
string = self.string.replacingOccurrences(of: "UU", with: "")
Label.text = string
}
func clear() {
string = "MI"
Label.text = string
}
#IBAction func rule1Button(_ sender: Any) {
rule1()
}
#IBAction func rul2Button(_ sender: Any) {
rule2()
}
#IBAction func rule3Button(_ sender: Any) {
rule3()
}
#IBAction func rule4Button(_ sender: Any) {
rule4()
}
#IBAction func clearButton(_ sender: Any) {
clear()
}
}
Code is just fine - you surely have wrong connection in your storyboard between #IBActions and Buttons.
Reconnect all of them and you should be fine.
If you right click on your UIButton in Storyboard, there is information to which IBAction it connects.
Check all buttons and fix broken ones.
Aside from that your code can be simplified a lot, and I encourage you to use didSet to keep your variable value with UILabel text.
var string : String = "" { //no need for default value here, as you are calling clear() on viewDidLoad(), better keep constants in one place
didSet {
Label.text = string
}
}
func rule1() {
if string.characters.last == "I" {
string = string + "U"
}
}
func rule2() {
string = string + string.replacingOccurrences(of: "M", with: "")
}
func rule3() {
string = self.string.replacingOccurrences(of: "III", with: "U")
}
func rule4() {
string = self.string.replacingOccurrences(of: "UU", with: "")
}
func clear() {
string = "MI"
}

How to have label text change to message after user types in textfield?

So I am very very new to coding in general and I am taking a class learning about creating apps in xcode. We were assigned to make our first app from scratch. My idea was to make a guessing game where the user is given a picture up close, and they are have to guess what it is. I want it where there's a label, textfield and button. They type their guess in the textfield, click the button to check their answer, and then the label text changes saying "you are wrong" or you are correct". I've looked all over and haven't found much on how to change a label's text depending on what is entered in the textfield. I assumed that I would use an if-else statement but it seems like that is only for integers. Any help on what to do? I've connected everything also. Thanks a lot in advance!
There you go:
import UIKit
import WebKit
class ViewController: UIViewController{
var dictionaryForQuestionAndAnswer = ["what is the best way to learn coding?":"trying","who is best person to ask question?":"Google"]
#IBOutlet weak var questionLabel: UILabel!
#IBOutlet weak var textField: UITextField!
var answerIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
questionLabel.text = ""
}
#IBAction func questionClicked(_ sender: Any) {
let random = randomInt(min: 1, max: 2)
if(random == 1)
{
answerIndex = 1
questionLabel.text = "what is the best way to learn coding?"
}
else
{
answerIndex = 2
questionLabel.text = "who is best person to ask question?"
}
}
#IBAction func answerClicked(_ sender: Any) {
if let answer = textField.text
{
if( answerIndex == 1 && answer == dictionaryForQuestionAndAnswer["what is the best way to learn coding?"])
{
questionLabel.text = "You are correct"
}
else if( answerIndex == 2 && answer == dictionaryForQuestionAndAnswer["who is best person to ask question?"])
{
questionLabel.text = "You are correct"
}
else
{
questionLabel.text = "You are wrong"
}
}
}
func randomInt(min: Int, max:Int) -> Int {
return min + Int(arc4random_uniform(UInt32(max - min + 1)))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Output

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

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!"
}
}

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

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