i have a label and a UIStepper, i need to increase the number of that label without lossing the letters ( Kd ) . my label will be like this "5.000 Kd" and when i increase the number i don't want to loss the ( Kd ) label.
this is my code
import UIKit
import GMStepper
class ViewController: UIViewController {
#IBOutlet var stepper: GMStepper!
#IBOutlet var price: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func stepper(_ sender: Any) {
let label = "5.000 Kd" as NSString
price.text! = String(label.doubleValue * stepper.value)
}
}
If you are hard-coding the string contents of the label, just maintain a numeric value and rebuild the label contents each time that value changes:
class ViewController: UIViewController {
#IBOutlet var stepper: GMStepper!
#IBOutlet var priceLabel: UILabel!
var price: Double = 5.0
#IBAction func stepper(_ sender: Any) {
let newValue = price * stepper.value
//Format the price with 3 decimal places
let priceString = String(format: "%.3f", newValue)
Construct a string with the formatted price and " Kd" and put it in the label
priceLabel.text = "\(priceString) Kd")
}
}
Consider using NumberFormatter to format currency:
let cf = NumberFormatter()
cf.currencyCode = "KWD"
cf.numberStyle = .currency
cf.string(from: 5000)
That respects the user's Locale.
Related
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 1 year ago.
Improve this question
So I came across this question that relates to mine and I was wondering how I can do this with a value from a segue data transfer. I want to be able to use my data transfer value as the original value and only have that value change if the stepper value changes.
For example my original value is 5 when the stepper value increases, 10, 15, 20, 25 ... and so on, and same thing for when it decreases. How can I go about doing this?
Here is my data transfer function :
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == Constants.Segues.fromEventDetailsToTicketForm {
guard let user = Auth.auth().currentUser else { return }
let vc = segue.destination as! TicketFormViewController
vc.ticketHolderName = user.displayName
vc.costOfEvent = selectedEventCost
vc.dateOfEvent = selectedEventDate
vc.navigationItem.title = selectedEventName
}
}
Here is the global variables in my destination vc:
#IBOutlet weak var nameOfTicketHolderLabel: UILabel!
#IBOutlet weak var nameOTicketHolderTextF: UITextField!
#IBOutlet weak var numberOfGuestsLabel: UILabel!
#IBOutlet weak var dateOfEventLabel: UILabel!
#IBOutlet weak var actualDateOfEvent: UILabel!
#IBOutlet weak var totalCostOfEventLabel: UILabel!
#IBOutlet weak var actualCostOfEvent: UILabel!
#IBOutlet weak var guestNumberCount: UILabel!
var ticketHolderName: String?
var costOfEvent: String?
var dateOfEvent: String?
var nameOfEvent: String?
And this is the function I use to connect everything:
func dataTransferVerification() {
if let nameToLoad = ticketHolderName {
nameOTicketHolderTextF.text = nameToLoad
}
if let costToLoad = costOfEvent {
actualCostOfEvent.text = costToLoad
}
if let dateToLoad = dateOfEvent {
actualDateOfEvent.text = dateToLoad
}
if let nameToLoad = nameOfEvent {
navigationItem.title = nameToLoad
}
}
The UIStepper func, I have no idea what to put in here:
#IBAction func guestsCount(_ sender: UIStepper) {
guestNumberCount.text = String(Int(sender.value))
}
Now I want to know, with what I got, how to use the cost value and make it original so when the stepper value changes, the original value never changes. Say it's $5.00 when the data transfers over, I only want $5 to be multiplied by the stepper value, I don't want it to change value.
First, you'll want to get a numerical version of your cost string.
At the top of your view controller:
private var costDecimal : Decimal = 0
In your "data transfer" as you call it (you could do this before or after the segue -- doesn't really matter):
let formatter = NumberFormatter()
formatter.numberStyle = .currency
if let number = formatter.number(from: str) {
let amount = number.decimalValue
print(amount)
self.costDecimal = amount
}
(taken from https://stackoverflow.com/a/41884823/560942)
Now, in your stepper:
#IBAction func guestsCount(_ sender: UIStepper) {
guestNumberCount.text = String(Int(sender.value))
//multiply sender.value by the cost that was passed in
let totalCost = Decimal(sender.value) * costDecimal
}
I am a beginner with Xcode and Swift. Below is my formula for the mortgage calculator. It is working correct in Playground but when I transfer it to the ViewController tab that is when Xcode is giving me a bunch of errors. Can someone please help?
let r: Double = interestRate / 1200
let n: Double = years * 12
let p: Double = pow(1 + r, n)
let monthPay = loan * r * p / (p - 1)
print(monthPay)
So in my View Controller
valueA is Loan Amount
valueB is Number of Payments
valueC is Interest Rate
underneath that you will have a calculate button that will print the results underneath in a label currently named results. It may be that when i rename everything to the values is when the issues occur.
ViewController Code
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var valueA: UITextField!
#IBOutlet weak var valueB: UITextField!
#IBOutlet weak var valueC: UITextField!
#IBOutlet weak var results: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func button(_ sender: Any) {
let a = Int(valueA.text!)
let b = Int(valueB.text!)
let c = Int(valueC.text!)
let answer = a! * c! * pow(1 + c!, b!) / (pow(1 + c!, b!))
results.text = "$\(answer)"
}
}
Your issue is that you are converting your textfield values to integers and trying to multiply them by the result of pow's method which returns a Double. Note that if the user enters an invalid value your app will crash if you force unwrap the result. Yo can use nil coalescing operator ?? to provide a default value .zero in case of failure. Try like this:
class ViewController: UIViewController {
#IBOutlet weak var valueA: UITextField! // loan amount
#IBOutlet weak var valueB: UITextField! // Number of Payments
#IBOutlet weak var valueC: UITextField! // Interest Rate
#IBOutlet weak var results: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func button(_ sender: Any) {
let loanAmount = Double(valueA.text!) ?? .zero
let numberOfPayments = Double(valueB.text!) ?? .zero
let interestRate = Double(valueC.text!) ?? .zero
let rate = interestRate / 100 / 12
let answer = loanAmount * rate / (1 - pow(1 + rate, -numberOfPayments))
results.text = Formatter.currency.string(for: answer)
}
}
extension Formatter {
static let currency: NumberFormatter = {
let formatter = NumberFormatter()
formatter.locale = .init(identifier: "en_US_POSIX")
formatter.numberStyle = .currency
return formatter
}()
}
This question already has answers here:
How can I use UserDefaults in Swift?
(14 answers)
Closed 4 years ago.
First time poster so sorry for the incorrect format/length of the question.
I am building an app in Xcode that allows users to input various inputs among numerous view controllers and then have output in a single view controller with results displayed through labels.
The raw inputted textfield data is stored into UserDefaults and can display them later in the resulting VC with no problem. Im having trouble with calculated outputs (in this example "papiresult") however.
Can anyone provide guidance how to print out the calculated result several view controllers later using UserDefaults?
This is the rough layout
Here is the code I have in the first ViewController:
import UIKit
let userDefaults = UserDefaults()
var papiresult = Double()
class ViewController1: UIViewController, UITextFieldDelegate {
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField2: UITextField!
#IBOutlet weak var textField3: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
textField1.delegate = self
textField2.delegate = self
textField3.delegate = self
}
//Declaring data input into UserDefaults//
#IBAction func sendDataToVC2(_ sender: Any) {
let systPA = Double(textField1.text!)
let diastPA = Double(textField2.text!)
let cvPressure = Double(textField3.text!)
papiresult = ((systPA!-diastPA!)/cvPressure!)
userDefaults.set(textField1.text, forKey: "PASP")
userDefaults.set(textField2.text, forKey: "PADP")
userDefaults.set(textField3.text, forKey: "CVP")
userDefaults.set(papiresult, forKey: "PAPI")
}
}
Here is the code in the last (result) view controller:
import UIKit
class ViewController3: UIViewController {
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var label3: UILabel!
#IBOutlet weak var label4: UILabel!
#IBOutlet weak var label5: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
//Recalling data from UserDefaults//
override func viewWillAppear(_ animated: Bool) {
if let data1 = userDefaults.object(forKey: "PASP") {
if let message1 = data1 as? String {
self.label1.text = message1}
}
if let data2 = userDefaults.object(forKey: "PADP") {
if let message2 = data2 as? String {
self.label2.text = message2}
}
if let data3 = userDefaults.object(forKey: "CVP") {
if let message3 = data3 as? String {
self.label3.text = message3}
}
if let data4 = userDefaults.object(forKey: "Age") {
if let message4 = data4 as? String {
self.label4.text = message4}
}
if let data5 = userDefaults.object(forKey: "PAPI") {
if let message5 = data5 as? Double {
self.label5.text = "\(message5)"}
}
}
Basically, you should use UserDefaults.standard rather than creating a new instance of UserDefaults class. So I think this code
let userDefaults = UserDefaults()
should be replaced with this:
let userDefaults = UserDefaults.standard
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
}
Just starting learning swift but stuck when trying to multiply an input with another number and display on a label. I get the error that the number isn't a string and tried to cast but didn't work.
class ViewController: UIViewController {
#IBOutlet weak var entry: UITextField!
#IBOutlet weak var answer: UILabel!
#IBAction func button(_ sender: Any) {
answer.text = entry.text * 2
}
}
You should cast the text into a Double, an Int etc., then convert the calculation to a string.
if let entry = Double(entry.text) {
answer.text = "\(entry * 2)"
}
or
if let entry = Int(entry.text) {
answer.text = "\(entry * 2)"
}
If you know that the entry will hold a number
answer.text = String(Int(entry.text)! * 2)
Using optional unwrapping instead
if let num = Int(entry.text) {
answer.text = String(num * 2)
}