I am having trouble with the whole string int thing.
I have managed to figure out how to convert each string to a number, however it returns as an optional and when I try to do anything with it I get nil.
My goal is to take 4 inputs from the user.
Each input textField is on separate view controllers.
Each view controller is fed data from variables passed from the view controller before it, using segue prepareForSegue.
Now I get to the last view controller and all the data passes fine, the problem is I cannot do any math with the values held in the variables since they are Strings.
Even after doing the conversion with .int() I cannot do math with them.
This is the last view controller classfile code:
class splitTheBillAmountViewController: UIViewController {
// capture passed data from previous View Controller
var numOfGuests = ""
var subTotalAmount = ""
var taxAmount = ""
var tipAmount = ""
#IBOutlet weak var dynamicTotal: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
println("Split The Bill!”)
// output variables data
println(numOfGuests)
println(subTotalAmount)
println(taxAmount)
println(tipAmount)
// store variables to new name
let string1 = numOfGuests
let string2 = subTotalAmount
let string3 = taxAmount
let string4 = tipAmount
// conversions
let guestNumber : Int? = string1.toInt()
let subTotalNumber : Int? = string2.toInt()
let taxAmountNumber : Int? = string3.toInt()
let tipNumber : Int? = string4.toInt()
// visual to see if numbers are converted .int()
println("\(guestNumber)")
println("\(subTotalNumber)")
println("\(taxAmountNumber)")
println("\(tipNumber)")
// store data to variable
let fTotal : Int? = (guestNumber)
// Update label with total
self.dynamicTotal.text = “fTotal"
// Do any additional setup after loading the view.
}
How can I do math with these variables?
I just need to add them up and divide by var numOfGuests
I'm not sure you want to use Ints for all these values, but that aside I ran this code:
var numOfGuests = "2"
var subTotalAmount = "25"
var taxAmount = "3"
var tipAmount = "2"
let string1 = numOfGuests
let string2 = subTotalAmount
let string3 = taxAmount
let string4 = tipAmount
let guestNumber : Int? = string1.toInt()
let subTotalNumber : Int? = string2.toInt()
let taxAmountNumber : Int? = string3.toInt()
let tipNumber : Int? = string4.toInt()
println("\(guestNumber)")
println("\(subTotalNumber)")
println("\(taxAmountNumber)")
println("\(tipNumber)")
it printed:
Optional(2)
Optional(25)
Optional(3)
Optional(2)
I then modified the print statements to:
println("\(guestNumber!)")
println("\(subTotalNumber!)")
println("\(taxAmountNumber!)")
println("\(tipNumber!)")
It printed:
2
25
3
2
In neither case was the output nil. I think you want to look at how your original strings are getting set. Maybe they're never getting reset from "".
BTW, back to the use of Int types for the calculations, I think you really want to use Float type, not Int.
This code:
var subTotalAmount = "25.15"
let string2 = subTotalAmount
var subTotalNumber = (string2 as NSString).floatValue
println("\(subTotalNumber)")
prints:
25.15
EDIT:
I played with copying your code, and I think you know that you have a typo that the compiler should warn you about. Once I fixed the typo, however I was getting a nil. I got this code to work:
var subTotalAmount = "25.15"
let string2 = subTotalAmount
var subTotalNumber = (string2 as NSString).floatValue
println("\(subTotalNumber)")
let text = NSString(format: "%.2f", subTotalNumber)
println(text)
This prints:
25.15
25.15
EDIT2:
Assuming you have all the numbers as floats, the total bill would be:
var fTotal:Float = subTotalNumber + taxAmountNumber + tipNumber
var costPerGuest:Float = fTotal / guestNumber
let fTotalText = NSString(format: "%.2f", fTotal)
let costPerGuestText = NSString(format: "%.2f", costPerGuest)
Related
this is my line of code.
budgetLabel.text = String((budgetLabel.text)!.toInt()! - (budgetItemTextBox.text)!.toInt()!)
the code works, but when I try to input a floating value into the textbox the program crashes. I am assuming the strings need to be converted to a float/double data type. I keep getting errors when i try to do that.
In Swift 2 there are new failable initializers that allow you to do this in more safe way, the Double("") returns an optional in cases like passing in "abc" string the failable initializer will return nil, so then you can use optional-binding to handle it like in the following way:
let s1 = "4.55"
let s2 = "3.15"
if let n1 = Double(s1), let n2 = Double(s2) {
let newString = String( n1 - n2)
print(newString)
}
else {
print("Some string is not a double value")
}
If you're using a version of Swift < 2, then old way was:
var n1 = ("9.99" as NSString).doubleValue // invalid returns 0, not an optional. (not recommended)
// invalid returns an optional value (recommended)
var pi = NSNumberFormatter().numberFromString("3.14")?.doubleValue
Fixed: Added Proper Handling for Optionals
let budgetLabel:UILabel = UILabel()
let budgetItemTextBox:UITextField = UITextField()
budgetLabel.text = ({
var value = ""
if let budgetString = budgetLabel.text, let budgetItemString = budgetItemTextBox.text
{
if let budgetValue = Float(budgetString), let budgetItemValue = Float(budgetItemString)
{
value = String(budgetValue - budgetItemValue)
}
}
return value
})()
You need to be using if let. In swift 2.0 it would look something like this:
if let
budgetString:String = budgetLabel.text,
budgetItemString:String = budgetItemTextBox.text,
budget:Double = Double(budgetString),
budgetItem:Double = Double(budgetItemString) {
budgetLabel.text = String(budget - budgetItem)
} else {
// If a number was not found, what should it do here?
}
I have been trying to check the mac battery level programmatically.it can be done on ios but i want to do it in mac.i found some resources on stackoverflow but those links were deprecated. Any Ideas?
First create a "Umbrella-Bridging-Header.h"
with the content:
#import <IOKit/ps/IOPowerSources.h>
then in main.swift
import Foundation
println("Hello, World!")
let timeRemaining = IOPSGetTimeRemainingEstimate ()
println("timeRemaining: \(timeRemaining)")
If you don't want to add Objective-C bridging and you need just to know a couple of values. Then you could use this function.
func getBatteryState() -> [String?]
{
let task = Process()
let pipe = Pipe()
task.launchPath = "/usr/bin/pmset"
task.arguments = ["-g", "batt"]
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String
let batteryArray = output.components(separatedBy: ";")
let source = output.components(separatedBy: "'")[1]
let state = batteryArray[1].trimmingCharacters(in: NSCharacterSet.whitespaces).capitalized
let percent = String.init(batteryArray[0].components(separatedBy: ")")[1].trimmingCharacters(in: NSCharacterSet.whitespaces).characters.dropLast())
var remaining = String.init(batteryArray[2].characters.dropFirst().split(separator: " ")[0])
if(remaining == "(no"){
remaining = "Calculating"
}
return [source, state, percent, remaining]
}
print(getBatteryState().flatMap{$0}) -> "AC Power", "Discharging", "94", "3:15"
pmset is a very old command line function which is very unlikely to change in the future. Of course this does not give extended properties of power options like mAh and so on, but it was enough for me, because I just needed to know is it charging or not and how much percent battery has currently.
Just my 2 cents. I understand if people will find this discouraging to use.
N.B. If charging - remaining will show how long until it's fully charged.
If discharging - it will show how long until it's discharged.
First, you can see the answer here on how to include Objective-C code in your swift project (very good post btw).
Then, check out the IOMPowerSource class. It should include everything you need to report the status of the computer's power information.
Swift 2 Version of the answer of #Just A Minnion
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var label: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
label.stringValue = String(getBatteryState().flatMap{$0})
}
func getBatteryState() -> [String?] {
let task = NSTask()
let pipe = NSPipe()
task.launchPath = "/usr/bin/pmset"
task.arguments = ["-g", "batt"]
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: NSUTF8StringEncoding) as! String
let batteryArray = output.componentsSeparatedByString(";")
let source = output.componentsSeparatedByString("'")[1]
let state = batteryArray[0].stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).capitalizedString
let percent = String.init(batteryArray[0].componentsSeparatedByString(")")[0].stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()))
var remaining = String.init(batteryArray[0].characters.dropFirst().split(" ")[1])
if (remaining == "(no") {
remaining = "Calculating"
}
return [source, state, percent, remaining]
}
}
So I'm making an app where you enter a time (1:32.40) and you then divide this time by a number (50). I made everything a Float so far, but that is clearly not right. How can I have the user enter the time like normal and then convert that to a Float that is easily divisible?
My Calculation function currently looks like this
func calculation() -> Bool{
raceDistance = txtRaceDistance.text
practiceDistance = txtPracticeDistance.text
goalTime = txtGoalTime.text
var fGoalTime = (goalTime as NSString).floatValue
var fRaceDistance = (raceDistance as NSString).floatValue
var fPracticeDistance = (practiceDistance as NSString).floatValue
dividedDistance = fRaceDistance / fPracticeDistance
answer = fGoalTime / dividedDistance
var answerFormat : NSString = NSString(format: "%0.2f", answer)
lblAnswer.text = String(answerFormat)
return true
}
fGoalTime is the only problem, because the user will be typing in something like (1:20.40)
I am assuming that you get an error for this line or just not the correct number.
var fGoalTime = (goalTime as NSString).floatValue
you will need to write a helper function timeStringToFloat(String) -> Float
In there you will want to use String.componentsSeparatedByString() maybe something like this:
func timeStringToFloat(timeString: String) -> Float {
let milliseconds = timeString.componentsSeparatedByString(".")[1]
let seconds = timeString.componentsSeparatedByString(.)[0].componentsSepatatedByString(":")[1]
let minutes = timeString.componentsSeparatedByString(":")[0]
//now we have them all as String
//maybe covert to float then add
let time = Float(minutes) * 60 + Float(seconds) + Float("0."+milliseconds)
return time
}
My challenge is twofold:
To pick individual strings from an array of similar strings, but only if a boolean test has been passed first.
"Finally" I need to concatenate any/all of the strings generated into one complete text and the entire code must be in Swift.
Illustration: A back of the envelope code for illustration of logic:
generatedText.text =
case Int1 <= 50 && Int2 == 50
return generatedParagraph1 = pick one string at RANDOM from a an array1 of strings
case Int3 =< 100
return generatedParagraph2 = pick one string at RANDOM from a an array2 of strings
case Int4 == 100
return generatedParagraph3 = pick one string at RANDOM from a an array3 of strings
...etc
default
return "Nothing to report"
and concatenate the individual generatedParagraphs
Attempt: Code picks a random element within stringArray1, 2 and 3.
Example of what the code returns:
---> "Sentence1_c.Sentence2_a.Sentence3_b."
PROBLEM: I need the code to ONLY pick an element if it has first passed a boolean. It means that the final concatenated string (concastString) could be empty, just contain one element, or several depending on how many of the bools were True. Does anyone know how to do this?
import Foundation
var stringArray1 = ["","Sentence1_a.", "Sentence1_b.", "Sentence1_c."]
var stringArray2 = ["","Sentence2_a.", "Sentence2_b.", "Sentence2_c."]
var stringArray3 = ["","Sentence3_a.", "Sentence3_b.", "Sentence3_c."]
let count1 = UInt32(stringArray1.count)-1
let count2 = UInt32(stringArray2.count)-1
let count3 = UInt32(stringArray3.count)-1
var randomNumberOne = Int(arc4random_uniform(count1))+1
var randomNumberTwo = Int(arc4random_uniform(count2))+1
var randomNumberThree = Int(arc4random_uniform(count3))+1
let concatString = stringArray1[randomNumberOne] + stringArray2[randomNumberTwo] + stringArray3[randomNumberThree]
Okay, I didn't pass a Bool, but I show concatenating three random strings from a [String]. I ran this in a playground.
import Foundation
var stringArray = [String]()
for var i = 0; i < 100; i++ {
stringArray.append("text" + "\(i)")
}
func concat (array: [String]) -> String {
let count = UInt32(stringArray.count)
let randomNumberOne = Int(arc4random_uniform(count))
let randomNumberTwo = Int(arc4random_uniform(count))
let randomNumberThree = Int(arc4random_uniform(count))
let concatString = array[randomNumberOne] + array[randomNumberTwo] + array[randomNumberThree]
return concatString
}
let finalString = concat(stringArray)
I am trying to format a number from a UITextfield, as its being typed, to a decimal with commas.
I have done so with the following code:
#IBAction func editingDidBegin(sender : AnyObject)
{
costField.addTarget(self, action: Selector("textFieldDidChange:"), forControlEvents: UIControlEvents.EditingChanged)
}
func textFieldDidChange(theTextField:UITextField) -> Void
{
var textFieldText = theTextField.text.stringByReplacingOccurrencesOfString(",", withString: " ", options: NSStringCompareOptions.RegularExpressionSearch, range: Range(start: theTextField.text.startIndex, end: theTextField.text.endIndex))
var formatter:NSNumberFormatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
var formattedOutput = formatter.stringFromNumber(textFieldText.bridgeToObjectiveC().integerValue)
costField.text = formattedOutput
}
The problem with this, is after four digits are entered, everything after the comma is deleted. For example if I enter 4000 it formats to 4,000, then if I type another number like 8 it reformats to 48.
Is there another way I can format this, maybe through IB or how can I fix the code?
Replace the line with:
var textFieldText = theTextField.text.stringByReplacingOccurrencesOfString(",", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: Range(start: theTextField.text.startIndex, end: theTextField.text.endIndex))
(I only removed the space between the double quotes).
Fact is, NSNumberFormatter doesn't like the added spaces in the string.
Works fine afterwards.
I know I am late to the party but this worked well for me.
var phoneNumber = " 1 (888) 555-5551 "
var strippedPhoneNumber = "".join(phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet))
It takes out the spaces and strips out the non decimal numeric characters.
The end result is "1888555551"
I've updated this answer to the newest version of swift. This borrows 90% from the two answers above however, also accounts for nil exception from the textfield when the textfield is cleared.
func textFieldDidChangeCommas(theTextField:UITextField) -> Void
{
if theTextField.text != nil {
var textFieldText = theTextField.text!.stringByReplacingOccurrencesOfString(",", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range: Range(start: theTextField.text!.startIndex, end: theTextField.text!.endIndex))
var formatter:NSNumberFormatter = NSNumberFormatter()
formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
if textFieldText != "" {
var formattedOutput = formatter.stringFromNumber(Int(textFieldText)!)
costField.text = formattedOutput
}
}
}