understand calculator code on Ios [closed] - ios

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

Related

Swift returning fatal error after pressing button and getting its currentTitle

So, I am following a video class of Switf for iOS 8 on iTunes (https://itunes.com/StanfordSwift if anyone is interested, its free), and well, now of course iOS 9 available and I think I am having a problem for the different versions and I cannot find ANYTHING on the web about this. I hope that anyone reading this can help me out a bit.
The project is about a Calculator, so I have in the UI the buttons with the numbers, these buttons sends its value (currentTitle) to my appendDigit function. Xcode does not mark any error, but still, at runtime when I press the button I get a fatal error, and honestly, I don't understand what is going on.
I tried setting and IF statement for when its available currentTitle or not, but well, this doesn't help at all since I need to be getting the buttons number.
Here is the code:
#IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber {
display.text = display.text! + digit
}else{
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}
}
The line that is causing the error is: let digit = sender.currentTitle!
Here is also a screenshot of what I am getting, seems that the button is sending the value empty... but as you can see, there are the numbers!
Thank you everyone !
There are numbers on the buttons, you claimed. But I think some of them, or one of them, don't.
The crash is caused by unwrapping an Optional value, which is the following line:
let digit = sender.currentTitle!
By looking at your layout in storyboard, I think you are connecting a lot of buttons to the same IBAction method, which is perfectly fine.
But as mentioned, some of them or one of them, whose currentTitle have not been set either programmatically or in storyboard ("title"), hence the crash.
So, please double check whether one of them or some of them whose currentTitle have not been set.
I was able to re-produce the error by deliberately leaving out currentTitle in one of the buttons. The crash occurred exactly like the one you're experiencing:
EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Or, one could proceed in a safer way:
#IBAction func appendDigit(sender: UIButton)
{
if let digit = sender.currentTitle
{
if userIsInTheMiddleOfTypingANumber
{
display.text = display.text! + digit
}
else
{
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}
}
}

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

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.

How to get the current word being typed?

I am making a custom keyboard extension for iOS 8 and am unsuccessful at trying to reflect the current word being typed on a UILabel sitting on top of the keyboard (think autocorrect). So far the code I wrote reflects the sentence before the cursor and not as it's being written, but as the cursor is moved from one position to another. What I am trying to achieve is exactly like the first autocorrect box in the native keyboard. Would anyone mind telling me what I am doing wrong?
Code:
override func textWillChange(textInput: UITextInput) {
var tokens = (self.textDocumentProxy as! UITextDocumentProxy).documentContextBeforeInput .componentsSeparatedByString(" ") as NSArray
var lastWord = tokens.lastObject as! String
println(lastWord)
bannerView?.btn1.setTitle(lastWord, forState: .Normal)
}
I've tried setting a condition whereby if beforeCursor contained either a space/period/comma to set the button title as "" but that is not efficient in the long run as I need to obtain words in order to be able to make an autocorrect feature.
Edit:
I've figured out how to get the word before the cursor (updated the code above), but not how to update the label as each letter is being added. func textWillChange(textInput: UITextInput)isn't working out. It's not me it's her.
Thanks!
You should use the textDocumentProxy property of your UIInputViewController:
let proxy = self.textDocumentProxy as! UITextDocumentProxy
To get the word being typed, I would suggest something like this:
var lastWordTyped: String? {
if let documentContext = proxy.documentContextBeforeInput as NSString? {
let length = documentContext.length
if length > 0 && NSCharacterSet.letterCharacterSet().characterIsMember(documentContext.characterAtIndex(length - 1)) {
let components = documentContext.componentsSeparatedByCharactersInSet(NSCharacterSet.alphanumericCharacterSet().invertedSet) as! [String]
return components[components.endIndex - 1]
}
}
return nil
}

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.
}
}

How to implement functions count and dropLast in swift, IOS?

I am making calculator in Swift. Stuck in backspace button. If user press wrong digit then backspace button would help to delete digit off the display.
Though I wrote dropLast function and works. It return appropriate result. How to use count method, don't understand the return type of count method.
#IBOutlet weak var display: UILabel!
#IBAction func backspace() {
//how to use count method to check collection of elements
//dropLast drop the last digit and display result
let dropedDigit = dropLast(display.text!)
display.text = dropedDigit
}
How about something like this:
private func dropLast(text: String) -> String {
let endIndex = advance(text.endIndex, -1)
return text.substringToIndex(endIndex)
}
It calculates the index where you want to make the cut (endIndex of text - 1) and then returns the substring to this index. This function should drop the last character.
I am not using count method here, but for you reference Swift 1.2 introduces count(<#x: T#>) method that calculates length of sets including Strings.
I know this thread is outdated, but I just went through the process of making this work, myself, in Swift 2.2, and figured I could help answer it.
#IBAction func delButton(sender: AnyObject) {
if display.text != nil {
var tempString = Array(display.text!.characters)
tempString.removeLast(1)
display.text = ""
for num in 0..<tempString.count {
display.text = display.text! + String(tempString[num])
}
}
}
Basically, we're checking to see that the display label has stuff in it, so we don't throw an error, and if so, making a variable in the scope of the function to hold the label's characters individually in a string. After that, we remove the last character from the array, clear out the label to ensure we aren't adding what's already there to our new values, then iterating through the updated array of characters and adding it to the label.
It's important to note that we are casting the values contained in the array as String, because they've been put into the array as character values, which operate differently than the string value the label is expecting.
Like I said, I know the thread is a little out of date, but I've been going through courses in Swift, and have discovered that while there is a plethora of information out there for Objective-C, there is perilously little information out there for how to do a lot of those things in Swift. Since the language is being updated repeatedly, I've noticed a growing divide between the two languages.

Resources