How to access a text field value and convert to double - swift

I am working on trying to build a tip calculator using swift but am running into a multitude of problems. I have a text box where the user enters in the bill amount and then they can adjust a slider to indicate the percentage that they want to tip. I have managed to get the slider and label associated with it to work where changing the value on the slider changes the label. However, I can't figure out how to get the text field to work. I attempted to create an action for the bill amount text box being changed but no matter what I put in it, it doesn't seem like the code is ever being executed (Whenever I run the code and click in the text box, the keyboard won't go away so maybe this is part of the problem?). All that I need is to be able to access the value in the text box field inside of my action when I click the calculate button but I can't seem to even get the value to show up much less convert it to a double so I can perform calculations on it. I am super new to swift and really want to learn what I am doing wrong. I have tried multiple tutorials and similar questions on here but none of them work. I appreciate all help y'all can give.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var txtBillAmount: UITextField!
#IBOutlet weak var lblTipPercentage: UILabel!
#IBOutlet weak var sldTipPercentage: UISlider!
#IBOutlet weak var lblTipAmount: UILabel!
#IBOutlet weak var lblTotalAmount: UILabel!
var tipPercentage = 10
var billAmount = ""
#IBAction func valueChanged(sender: AnyObject) {
let currentValue = Int(sldTipPercentage.value)
lblTipPercentage.text = "\(currentValue)%"
tipPercentage = currentValue
}
#IBAction func btnCalculate(sender: AnyObject) {
lblTipAmount.text = "\(billAmount)"
}
#IBAction func txtBillAmountValueChanged(sender: AnyObject) {
}
override func viewDidLoad() {
super.viewDidLoad()
//txtBillAmount.delegate = self
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func btnReset(sender: UIButton) {
sldTipPercentage.value = 10
lblTipPercentage.text = "10%"
txtBillAmount.text = ""
lblTipAmount.text = "--"
lblTotalAmount.text = "--"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is a screenshot of how the UI looks
Error that I am getting

[Xcode >= 7 and Swift > 2]
Try like this
#IBAction func btnCalculate(sender: AnyObject) {
if let textValue = txtBillAmount.text {
let billAmnt = Double(textValue)
let tipAmount = (billAmnt*tipPercentage)/100
lblTipAmount.text = "\(tipAmount)"
}
}
If you are using Xcode-6 and Swift < 2 then try the following way. because String initializer for Double is only available in Swift 2 (Xcode 7). [Recommend update your Xcode]
#IBAction func btnCalculate(sender: AnyObject) {
let billAmnt = (txtBillAmount.text! as NSString).doubleValue
let tipAmount = (billAmnt*tipPercentage)/100
lblTipAmount.text = "\(tipAmount)"
}

Related

How do I assign Y to X?

I couldn't figure out how to copy value of variable into another variable in Swift, an example code for this in python would be
def assignVariable():
x=1
y=x
return y
RESULT 1
When I did this it doesn't seem to work in Swift. Is there any solution to this or am I doing something wrong?
Edit: problem is at
var originalCount=countDown
it gave me Use of unresolved identifier 'countDown' but when I assign it literally it works. Here's my swift code
import Cocoa
class MainWindow: NSWindowController {
var hitCount = 0
var started:Bool = false
var timer = 10
var colorList: [NSColor] = [ NSColor.black,NSColor.blue,NSColor.brown,NSColor.cyan,NSColor.darkGray,NSColor.gray,NSColor.green,NSColor.lightGray,NSColor.magenta,NSColor.orange,NSColor.purple,NSColor.red,NSColor.white,NSColor.yellow]
#IBOutlet weak var button1: NSButton!
#IBOutlet weak var scrubber1: NSScrubber!
#IBOutlet weak var display: NSTextField!
override func windowDidLoad() {
super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
var countdown=10
var originalCount=countDown
//(countdown,originalCount) = (10,10) //it works if i use this instead
func startGame(){
if(countDown>0 || started==true){
display.stringValue=String(countDown)
countDown-=1
let seconds = 1.0
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
self.startGame()
}
}else{
display.stringValue="Done "+String(hitCount)+" Taps in " + String(originalCount) + "Tap to RESET"
started=false
countDown=10;
}
}
#IBAction func labelPress(_ sender: Any) {
display.stringValue="__RESET__"
hitCount=0
countDown=10
started=false
}
#IBAction func buttonPressed(_ sender: Any) {
if started==false{
startGame()
}
button1.bezelColor = colorList[Int.random(in: 0..<colorList.count)]
started=true
button1.title=String(hitCount)
hitCount+=1
}
}
You can't initialise one variable with another at the top level in your class. Looking at your code I don't think that originalCount needs to be a property, move it inside startGame() instead and make it a local variable and also use let since it isn't changing
var countdown=10
func startGame(){
let originalCount = countDown
if(countDown>0 || started==true){
...
}

NSPopUpButton selection to Float Swift 4

I am trying to get a String value to a Float value from a NSPopUpButton.
E.g. I have 3 number selections. 50, 20, 10. When the user selects one of the numbers I would like a calculation made into a Float value.
I know this may be something very simple but I am new and I can't find anything on Stackoverflow. Any help would be appreciated. Here is an example of the code I have.
#IBOutlet weak var userInput: NSTextField!
#IBOutlet weak var result: NSTextField!
#IBOutlet weak var userMenuSelection: NSPopUpButton!
override func viewDidLoad() {
super.viewDidLoad()
userMenuSelection.removeAllItems()
userMenuSelection.addItems(withTitles: ["50", "20", "10"])
}
#IBAction func pushButtonforResult(_ sender: Any) {
/*
Not sure how to take the selected userMenuSelection and multiply it by the users input to get my result in a float.
E.g. look below. This of course does not work because the menu items are strings.
*/
result.floatValue = userMenuSelection * userInput.floatValue
}
Hope this makes sense to what I am asking.
As you see, your userMenuSelection has titles representing the Float values as String.
You can simply retrieve the selected title and convert it to Float:
#IBAction func pushButtonforResult(_ sender: Any) {
var selectedValue = Float(userMenuSelection.titleOfSelectedItem ?? "0") ?? 0.0
result.floatValue = selectedValue * userInput.floatValue
}
You can try
let arr = ["50", "20", "10"]
//
#IBAction func pushButtonforResult(_ sender: NSPopUpButton) {
let selectedValue = Float(arr[sender.selectedTag()])!
Result.floatValue = selectedValue * userInput.floatValue
// OR
let selectedValue = Float(sender.selectedItem!.title)!
result.floatValue = selectedValue * userInput.floatValue
}

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

Adding Ints in a UILabel in Swift

I am making an app where there is a football field and when you click on the Score Zone 7 points are added to the UILabel that marks score. But I have only been able to display a 7 once and if I click again the seven appears again; I want it to add 7 more to make a 14.
#IBAction func touchdownMD(sender: AnyObject) {
var pointsMD = Int()
scoreMD.text = "\(pointsMD + 7)"
}
#IBOutlet var scoreSH: UILabel!
When you initialize pointsMD inside of the touchdownMD: function, it starts from 0 whenever the function is called.
In order to fix this, you need to declare it at the class level. For example:
var pointsMD = Int() //initialize pointsMD at the class level
#IBAction func touchdownMD(sender: AnyObject){
pointsMD+=7 //add 7 to pointsMD
scoreMD.text = "\(pointsMD)"
}
That way, pointsMD will not reset whenever touchdownMD: is called, it will instead just increment as needed.
So, here's what your code could look like:
var pointsMD = Int()
#IBAction func touchdownMD(sender: AnyObject) {
pointsMD+=7
scoreMD.text = "\(pointsMD)"
}
#IBOutlet var scoreSH: UILabel!

Swift: label text --> "fatal error: unexpectedly found nil while unwrapping an Optional value"

like it says in the title, i am trying to change label text upon click of a button. Error appears at line self.playerChoice.text = "You: Rock"
import UIKit
class ViewController: UIViewController {
var player : Int = Int()
#IBOutlet weak var readyLabel: UILabel!
#IBAction func noButton(sender: AnyObject) {
exit(0)
}
// ---------------------------------------------------------
#IBOutlet var computerChoice: UILabel!
#IBOutlet var playerChoice: UILabel!
#IBOutlet var score: UILabel!
// Variables -------------------------------------------------
let Rock : String = "Rock"
let Paper : String = "Paper"
let Scissors : String = "Scissors"
//------------------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
// ----------------------------------------------------------------
#IBAction func rockButton(rockbut: UIButton) {
player = 0
var ai = arc4random_uniform(3)
self.playerChoice.text = "You: Rock"
}
#IBAction func paperButton(paperbut: UIButton) {
player = 1
var ai = arc4random_uniform(3)
self.playerChoice.text = "You: Paper"
}
#IBAction func scissorsButton(scissorsbut: UIButton) {
player = 2
var ai = arc4random_uniform(3)
self.playerChoice.text = "You: Scissors"
}
}
I ran into this problem and it turned out that the labels that I was trying to edit didn't exist at the time the code ran.
Turns out I was referencing the same view controller from a parent view and a child container view. The labels I was trying to change were only in the container view but as both views loaded it ran the view controller for both so it tried to find the labels that didn't exist in the parent view and threw the above error.
So the lesson I learned... If a reference to a view object is throwing a NIL..
The View isn't properly mapped to the View Controller.
The object within the view isn't mapped to the referencing IBOutlet.
Or as in my case, there are multiple views connected to the same View Controller and references to view objects in one view are not being found in the other.
Looks like player choice is not initialized.
#IBOutlet var playerChoice: UILabel!
Maybe the connection between the outlet and InterfaceBuilder/Storyboard is lost. Try to connect it again.
I've created a small demo and everything works fine:
Check if the circles at the left side of your IBOutlet are filled. Otherwise the connection is lost.
What fixed this for me (and it gets me everytime, especially when you are new to using storyboards) is to make sure that you are initializing your view controller like so :
slideShowVC = (UIStoryboard(name: "Main",bundle: nil).instantiateViewControllerWithIdentifier("WWPhotoSlideShowVC") as! WWPhotoSlideShowVC)
instead of the stand alone xib way :
slideShowVC = WWSlideShowVC()
Or else all your outlets will be nil na many headaches will soon follow.
I ran into the same issue in Xcode 6.2.
I use individual XIBs instead of storyboards. The problem for me was that with Swift, Xcode does not automatically associate the XIB with the view controller if the names are the same. Hence the IBOutlets for the labels are pointing to nil giving the fatal.
You can change the viewcontroller.xib to be called modulename.viewcontroller.xib so that xcode can associate it with the view controller and the issue goes away.
More options are mentioned on this thread:
Can't Load UIViewController XIB file in Storyboard in Swift
I have tried this code and it working fine for me:
class ViewController: UIViewController {
var player : Int = Int() //Declare this globally
#IBOutlet weak var readyLabel: UILabel!
#IBAction func noButton(sender: AnyObject) {
exit(0)
}
// ---------------------------------------------------------
#IBOutlet var computerChoice: UILabel!
#IBOutlet var playerChoice: UILabel!
#IBOutlet var score: UILabel!
// Variables -------------------------------------------------
let Rock : String = "Rock"
let Paper : String = "Paper"
let Scissors : String = "Scissors"
//------------------------------------------------------------
#IBAction func rockButton(rockbut: UIButton) {
player = 0
var ai = arc4random_uniform(3)
self.playerChoice.text = "You: Rock"
}
#IBAction func paperButton(sender: UIButton) {
player = 1
var ai = arc4random_uniform(3)
self.playerChoice.text = "You: Paper"
}
#IBAction func scissorsButton(sender: UIButton) {
player = 2
var ai = arc4random_uniform(3)
self.playerChoice.text = "You: Scissors"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var p : String = "Undecided"
if (player == 0) {
var p: String = "Rock"
} else if (player == 1) {
var p: String = "Paper"
} else if (player == 2) {
var p: String = "Scissors"
}
}
}