Passing a Swift variable from one IBAction to another [closed] - ios

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
In my application I have a "Play" button which creates two random numbers and creates a string for those numbers, which is then used to fill in the two UIImage holders for cards (cards 0-10 which are set in a Array). Then the two random numbers are added together.
There is an input field where the user can input their guess and then hit "Submit". If their answer is correct it will flash "Correct". If the answer is wrong, it will flash Try Again. My question is how can I get the total variable passed to the Submit so I can successfully create my if else statements?
So here is the end code to the Play button Action which works perfectly
let total = firstRandomNumber + secondRandomNumber
Here is the code for the Submit button which is giving me an error
#IBAction func submit(sender: UIButton) {
correct.hidden = (true)
tryagain.hidden = (true)
let guess = Double(text.text!)
if guess = total {
correct.hidden = (false)
}
The error I'm getting is "undefined variable total"

So the variables are not going to be PASSED to Submit() because that's the function the button calls. The button can careless about your two variables. Instead you'll want to have two Global variables (in this case the two random numbers) and request them in Submit. These are variables that was created outside any functions and are set when they need to be set. So lets see how you'd do that with your code:
// Two random numbers (global)
var a: Int?
var b: Int?
func generateRandomNumber() {
a = // assign a to the number generator value
b = // same as above
}
func submit() { // your button call
if let userGuess = text.text { // do if let instead of ! it's safer
let total = a + b
if userGuess == total { // our check remember == is different from =
correctView.hidden = false
} else { // if it's wrong show this view
tryAgainView.hidden = false
}
}
}
Obviously there's a bunch missing but you can get the main idea. Let me know if these anything I can answer about this method.

Related

Swift array not maintaining items properly

Bear with me as I try to describe this. I'm creating a trivia game in Xcode which reads questions, answer choices, and the correct answer expected from a file. The file contains 20 questions worth of data separated by an asterisk (*) for each line. The first line is the question, the next four lines are the choices, and the last line is the correct answer (this format is repeated for each question).
In the code I create a string (questionFileContents) which contains all the text from the text file containing the questions.
In my createArrays() method I create a new array which contains each piece of the file as a separate string (determined by where the * is). I create a new array which contains 6 pieces of info (question, choices, and the correct answer) - this array gets loaded into the arrayOfArrays once it is full with the 6 pieces of info and then it moves on to adding a new array with another 6 pieces of info.
Hopefully, that makes sense.
The problem that I am getting is that when I use print(arrayOfArrays.count) it states that I only have 17 items within that array even though I should be getting 20 (for each of the 20 different questions). When I add a bunch of empty text to the text file (equivalent to the number of questions the arrayOfArrays was disregarding) it then disregards that and includes the questions which it had been disregarding before. So... what is causing the arrayOfArrays to not contain the 20 items it should be containing? Is this a compiler error, if not, where is my logic wrong?
I've included my code as well as the text file from which I am reading the question contents.
Thanks in advance!
import UIKit
class QuestionAnswerController: UIViewController {
#IBOutlet weak var textViewForQuestions: UITextView! // the textview which displays the current question text
#IBOutlet weak var questionNumberView: UITextView!
#IBOutlet weak var button1Text: UITextView! // these are the different textviews which correspond to the buttons and answers
#IBOutlet weak var button2Text: UITextView!
#IBOutlet weak var button3Text: UITextView!
#IBOutlet weak var button4Text: UITextView!
#IBOutlet weak var scoreView: UITextView! // textview which indicates the user's score
var questionFileContents : String = "" // blank string which will contain the different contents (questions, choices, answers)
var arrayOfArrays : Array = [[String]]() // array which contains the different arrays with their question components
var currentTrackerOfArrays : Int = 0 // keeps track of which item from the string is being added to the addingToArray array
var currentAnswer : String = "" // keeps track of what the correct answer is for this question
var userScore : Int = 0 // keeps track of the user's current score
var userSelectedAnswer : String = "" // keeps track of the user's current answer provided when they hit the answer button
var currentQuestion : Int = 1
#IBAction func answerButtonPressed(_ sender: UIButton) { // do something when the user presses a button
if sender.tag == 0 { // if the button pressed is (insert num here), do this
// sets the user's selected answer to whatever they chose
userSelectedAnswer = """
A
"""
checkForCorrectAnswer() // checks to see if the answer was correct
}
else if sender.tag == 1 {
userSelectedAnswer = """
B
"""
checkForCorrectAnswer()
}
else if sender.tag == 2 {
userSelectedAnswer = """
C
"""
checkForCorrectAnswer()
}
else if sender.tag == 3 {
userSelectedAnswer = """
D
"""
checkForCorrectAnswer()
}
newQuestionSet() // updates the list of choices as well as the question which is presented to the user
}
override func viewDidLoad() { // upon the view loading, do...
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
createArrays()
updateUI()
newQuestionSet()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func createQuestionsListString() { // takes all content from the questions file and makes a string with the content
if let filepath = Bundle.main.path(forResource: "TriviaQuestions-Formatted", ofType: "txt") { // the main filepath for the file
do {
let contents = try String(contentsOfFile: filepath) // attempts to make string with file
questionFileContents = contents // sets the questionFileContents variable to the contents of the file
} catch let error as NSError { // in the event of an error, do...
// contents could not be loaded
print("Contents could not be loaded.")
print(error.description)
}
}
}
func newQuestionSet() { // sets all the different elements of the user interface for the next question
if arrayOfArrays.count > 0 { // if there is still questions left in the array, do...
let randomQuestionInt = Int(arc4random_uniform(UInt32(arrayOfArrays.count) - 1)) // chooses a random question number
textViewForQuestions.text = arrayOfArrays[randomQuestionInt][0] // sets the text of the question
button1Text.text = arrayOfArrays[randomQuestionInt][1] // these set the different choices' text to be the choices from the question array
button2Text.text = arrayOfArrays[randomQuestionInt][2]
button3Text.text = arrayOfArrays[randomQuestionInt][3]
button4Text.text = arrayOfArrays[randomQuestionInt][4]
currentAnswer = arrayOfArrays[randomQuestionInt][5] // sets the current correct answer
arrayOfArrays.remove(at: randomQuestionInt) // prevents repeated questions
// print(arrayOfArrays.count)
}
else { // in the event that there are no more questions remaining, do...
textViewForQuestions.text = "Finished."
currentAnswer = ""
}
}
func updateUI() { // updates the user interface with the current score
scoreView.text = "Score: \(userScore)"
questionNumberView.text = "Question number: \(currentQuestion)"
}
func checkForCorrectAnswer() {
if userSelectedAnswer == String(currentAnswer) { // if the user selected answer is the same as the correct answer for the question, do...
userScore += 1 // update the score
currentQuestion += 1
updateUI() // update the UI with the new score
}
else {
currentQuestion += 1
updateUI()
}
}
func createArrays() { // creates the arrays for the questions and the array of arrays
createQuestionsListString() // calls the method to make the string from the questions file
let questionPiecesArray = questionFileContents.split(separator: "*") // breaks apart the string based on where an asterix is located (and puts the pieces in an array)
var addingToArray : Array = [String]() // the array which contains the different components of the question (question, choices, correct answer) which will be added to the array of arrays
for _ in questionPiecesArray { // for however many pieces are in the questionPiecesArray, do...
if addingToArray.count >= 6 { // if the array storing the current question gets filled with 6 or more objects, do...
arrayOfArrays.append(addingToArray) // adds the question array to the array containing all the question arrays
addingToArray.removeAll() // empties the question array to make room for new question components
}
else if addingToArray.count <= 6 { // if the array isn't full, do...
addingToArray.append(String(questionPiecesArray[currentTrackerOfArrays])) // addsar the current question component (from questionPiecesArray) to the question array
currentTrackerOfArrays += 1 // moves onto the next piece of information
}
}
print(arrayOfArrays.count)
print(questionPiecesArray.count)
print(arrayOfArrays)
// current problem, the array of arrays is maxing out at holding 17 arrays and won't hold anymore ...
// this problem makes no sense because the print(questionPiecesArray.count) method is showing ...
// that there are 120+ objects in the array so the for loop should add that many objects to the various arrays
// through testing it seems that the arrayOfArrays always has 4 less arrays than it should
// I'll just repeat the last 4 questions again so that they get included in the mix (?)...
// Perhaps it would be better to put in meaningless text for the last 4 blank question templates so that if a glitch occurs it will be more obvious
// Yeah, I'll do that
// Test: it seems to be working well with the empty text
}
}
This is what is contained in the txt file it is reading from:
How do crickets hear?*
Through their wings*
Through their belly*
Through their knees*
Through their tongue*
C*
Which American city invented plastic vomit?*
Chicago*
Detroit*
Columbus*
Baltimore*
A*
In ‘Ben Hur’, which modern thing can be seen during the chariot scene?*
A waitress*
A car*
A postbox*
A street lamp*
B*
What was Karl Marx’s favorite color?*
Brown*
Blue*
Red*
Purple*
C*
What’s the best way to stop crying while peeling onions?*
Lick almonds*
Suck lemons*
Eat cheese*
Chew gum*
D*
How old was the youngest Pope?*
11*
17*
22*
29*
A*
Which animal sleeps for only five minutes a day?*
A chameleon*
A koala*
A giraffe*
A beaver*
C*
How many words in the English language end in “dous"?*
Two*
Four*
Six*
Eight*
B*
One human hair can support how many kilograms?*
Three*
Five*
Seven*
Nine*
A*
The bikini was originally called the what?*
Poke*
Range*
Half*
Atom*
D*
Which European city is home to the Fairy Investigation Society?*
Poznan*
Dublin*
Bratislava*
Tallinn*
B*
What’s a frog’s favourite colour?*
Blue*
Orange*
Yellow*
Brown*
A*
Which one of these planets rotates clockwise?*
Uranus*
Mercury*
Pluto*
Venus*
D*
What perspires half a pint of fluid a day?*
Your scalp*
Your armpits*
Your feet*
Your buttocks*
C*
St Stephen is the patron saint of who?*
Plumbers*
Bricklayers*
Roofers*
Carpenters*
B*
Which country leads the world in cork production?*
Greece*
Australia*
Spain*
Mexico*
C*
On average, what do you do 15 times a day?*
Laugh*
Burp*
Break wind*
Lick your lips*
A*
What colour was Coca-Cola originally?*
Red*
Purple*
Beige*
Green*
D*
Bubble gum contains what?*
Plastic*
Calcium*
Rubber*
Pepper*
C*
The inventor of the paint roller was of which nationality?*
Hungarian*
Canadian*
Norwegian*
Argentinian*
B*
Please note: there were no problems with reading from the text file.
The problem is in your else if statement. Use this for loop to get the right result (I've tested it):
for item in questionPiecesArray {
// always add the current item to the array
addingToArray.append(String(item))
// if it was last for the current question, reset the addingToArray
if addingToArray.count >= 6 {
arrayOfArrays.append(addingToArray)
addingToArray.removeAll()
}
}
Also, using this you won't need currentTrackerOfArrays anymore.

Add data to a new line in UITextView every time button is pressed

I currently have a function that, when a button is pressed, takes a value that is determined from a UIStepper and adds it to a list of numbers. When I press the Add Tip button, it correctly displays the tip amount in the text view, but when I add a new value it replaces it rather than adding it underneath.
Here is the function:
#IBAction func addTipButton(_ sender: UIButton) {
let tipDollarCent = dollar + cent
sampleLog.text = "\(tipDollarCent)\n"
totalLabel.text = tipDollarCent
}
sampleLog is the Text View that needs to take a variable amount of lines of data, depending on how many time the user presses addTipButton
I am aware that my best course of action is probably to do an incremental loop, and I have tried implementing a separate addNewLine function, but tipDollarCent was out of scope and gave me an error.
I also initially tried adding sampleLog.text = "\(tipDollarCent)\n" += "\(tipDollarCent)\n" directly to the function.
I am hoping someone would be able to patiently and kindly explain to me what the best loop to use in this scenario would be, and how to properly implement it.
Here is a screenshot of my app so it is easier to see what I am trying to accomplish
If you want the textView text to append the newly created string, you can use the compound-assign operator for addition += to concatenate the what you previous had and grow it with a new string value.
var foo:String = "Foo"
let bar:String = "Bar"
foo += bar /* FooBar */ /* foo = foo + bar */
And for your comment on additions with doubles, the compound operator will also work with same-typed operands.
var pi:Double = 3.0
let fourteen:Double = 0.14
pi += fourteen /* 3.14 */ /* pi = pi + fourteen */

understand calculator code on Ios [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to see how programmers explain this code, and What is the utility of the last line?
I am a new beginner and I am not sure if I am understanding this code properly. Hope you are going to give nice detailed answers so I can get my benefit and also the other new beginners ever after.
var UserIsInTheMiddleOfTyping = false
#IBAction func TouchedDigit(_ sender: UIButton) {
let digit = sender.currentTitle!
let CurrentTextinDisplay = Display.text!
if UserIsInTheMiddleOfTyping {
Display.text = CurrentTextinDisplay + digit
}else{
Display.text = digit
}
UserIsInTheMiddleOfTyping = true
}
}
This is a brief explanation based on my interpretation of this fragment of code.
Apparently, before the method is executed we don't know if the user is typing anything or not since the method could have been already called, therefore UserIsInTheMiddleOfTyping could be either true or false
var UserIsInTheMiddleOfTyping = false
When he taps a number on the calculator the method TouchedDigit(_ sender: UIButton) is triggered.
A new constant digit is created and set to the sender's title which is an instance of UIButton (The title property is the displayed name of the button, e.g. 1,2,3..)
A new constant CurrentTextinDisplay is created and set to the content of what I suppose to be a UITextField (Unwrapping it, therefore is not null)
let CurrentTextinDisplay = Display.text!
If the user was typing something before the method was called (Pretty bad code implementation though), we append the digit constant created before to the content of the Display instance which (I guess) holds the digits already typed.
if UserIsInTheMiddleOfTyping {
Display.text = CurrentTextinDisplay + digit
}
Otherwise, if the user is entering the first digit, whe set the Display instance to hold this first digit
else{
Display.text = digit
}
Before returning the method sets UserIsInTheMiddleOfTyping to true.
(Next time the method is triggered we will enter the if statement for sure and append the new digit.)
UserIsInTheMiddleOfTyping = true
I would personally shrink the code as follows:
//There is no need to save in a variable if the user is in the middle of typing
//Because he will be in this state only when the method is triggered, therefore just shrink as follows:
#IBAction func TouchedDigit(_ sender: UIButton) {
//Safe unwrapping of sender.currentTitle:
if let actualDigit = sender.currentTitle {
//Safe unwrapping of Display.text:
if let actualText = Display.text {
Display.text = actualText + actualDigit
}
}
}
Hope this helped, if so mark the question as correct.
Bye

Trouble appending values to stack in swift

I've been trying to get this code to work but of no use!
So the interface has a few buttons with numerical numbers in them (like a calculator). The task is to get the numerical values (in string) by using currentTitle method, converting into double and appendig to a stack (operandStack).
I was able to get one value onto stack but after that, the button the does it greys out and I can't do anything more with it.
#IBAction func addOntoStack() {
operandStack.append(dispValueInDouble)
print("operandStack = \(operandStack)")
}
var dispValueInDouble:Double{
doubleLabel = NSNumberFormatter().numberFromString(label.text!)!.doubleValue
print("label: \(doubleLabel)")
return doubleLabel
}

Using UIButton Text as Text Input - Swift

Hello I have a profilelbl variable as below which is a uibutton. I want the text of the button to be an input in my database (parse). But I couldn't figured it out. I tried lots of things but still getting error:
#IBOutlet weak var profileLbl: UIButton!
var notification = PFObject(className: "notifications")
notification["actionReceiverName"] = profilelbl.text /*not working*/
/* also tried
notification["actionReceiverName"] = sender.profilelbl.text
notification["actionReceiverName"] = profilelbl.title */
you can do it easy like that
if let button = profilelbl as? UIButton {
if let title = button.titleForState(.Normal) {
println(title)
notification["actionReceiverName"] = title
}
}
Using UI objects to save/load data is a very bad idea. Using user-visible strings programmatically is an even worse idea. #ÖzgürErsil answered the question you asked, but the better answer to your question is "Don't do that. Ever."
Here are 2 examples where your approach will fail:
If 6 months later you want to change your UI and rename your button,
you won't remember that the button title is used in code and your
code will break. To that you would have to alter your database to
use a different string value.
If you decide to localize your app for foreign
languages, the button titles will come up in the local language, and
your code will break. There is no clean way to fix this problem,
since each local language would use a different version of the
button title.
It would be better to put unique tag numbers on your buttons, then look up text strings using the tags and pass those strings to your database.
Say you have button tags starting at 100.
You'd use code like this:
let buttonStrings = ["button1", "button2", "button3"]
let baseButtonTag = 100;
#IBAction func handleButton(sender: UIButton)
{
let tag = sender.tag
if tag >= baseButtonTag && tag < baseButtonTag + buttonStrings.count
{
let index = sender.tag - baseButtonTag
let buttonString = buttonStrings[index];
//Now use buttonString with your database as desired.
}
}

Resources