macOS Swift TextField.stringValue not returning updated value until I click on something else - swift

I apologize if this has been asked before but I couldn't find what I was looking for online over the last few hours. I'm still functional a noob with swift.
I am trying to store the stringValue of a TextField when I click a NSButton. If I click anywhere and then click on the NSButton the code works perfect but if I don't click the stringValue is still reporting the previous value.
#IBOutlet weak var NameText: NSTextField!
#IBOutlet weak var SaveChangesAccountButton: NSButton!
var selectedAccountItemNumber = NSInteger()
#IBAction func SaveAccountChanges(_ sender: Any)
{
let AccountName = NameText.stringValue
AccountingData.instance.book.account[selectedAccountItemNumber].name = AccountName
}

You have to call validateEditing() on the text field.
And please conform to the naming convention that variable and function names start with a lowercase letter and don't use NSInteger in Swift.
#IBOutlet weak var nameText: NSTextField!
#IBOutlet weak var saveChangesAccountButton: NSButton!
var selectedAccountItemNumber = 0
#IBAction func saveAccountChanges(_ sender: Any)
{
nameText.validateEditing()
let accountName = nameText.stringValue
AccountingData.instance.book.account[selectedAccountItemNumber].name = accountName
}

Related

how to use emojis in my project in Xcode and declare them in a dictionary array?

simply I have a uiimage and want to use one of the emojis in that . how can I get some of these emojis and place into my project? this is the place I ll get them from.
https://apps.timwhitlock.info/emoji/tables/iso3166
one more question . next to my uiimage I have a uilabel for currency codes. so to use the image along with the corresponding code do I need to use a dictionary like :
var dict = ["EUR": "imagenameinString"]
or
var dict = ["code" : "EUR", "image": "imagenameinString"
i want to call the currency code and related image/emoji together. This is my code below using a string value for emoji but I get error in this way naturally. how do I edit this code to work? Thank you!
class ViewController: UIViewController {
#IBOutlet weak var amountText: UITextField!
#IBOutlet weak var amountText2: UITextField!
#IBOutlet weak var fromLabel: UILabel!
#IBOutlet weak var fromImage: UIImageView!
#IBOutlet weak var toImage: UIImageView!
#IBOutlet weak var toLabel: UILabel!
let flag = "\u{1F1F8}\u{1F1EA}"
var currencyManager = CurrencyManager()
var from: String = "EUR"
var to: String = "TRY"
var amount: String = "0"
override func viewDidLoad() {
super.viewDidLoad()
amountText.delegate = self
currencyManager.delegate = self
fromImage.image = flag
}

Secure text .echosbullets not working for password field

Here's what I've got:
#IBOutlet weak var password: NSSecureTextField!
#IBOutlet weak var shwpswd: NSButton! //Checkbox
#IBOutlet weak var pswdcell: NSSecureTextFieldCell! //Cell
#IBAction func shwpswd(_ sender: Any) {
if(shwpswd.state == 1) {
pswdcell.echosBullets = false // Turn the Secure text into regular text
}
else if(shwpswd.state == 0) {
pswdcell.echosBullets = true // Secure text
}
}
Everything seems to run fine, except the text in the password field doesn't change states between echoing bullets and echoing the real text. Everything is linked together properly too - Cell is within the text field, password button is in the view and the outlet works. I'm wondering if this is another one of the "Swift on mac < Swift on iOS cases".
EDIT: Here is the final solution, should anyone care to see it:
#IBOutlet weak var shwpswd: NSButton! //Checkbox
#IBOutlet weak var visPswd: NSTextfield! //hidden regular box to show chars
#IBOutlet weak var password: NSSecureTextField! //visible initial secure box
#IBAction func shwpswd(_ sender: Any) {
if(shwpswd.state == 1) {
self.visPswd.stringValue = self.password.stringValue //Sync both the text fields
self.password.isHidden = true //hide the secure field
self.visPswd.isHidden = false //show the real character echo field
}
else if(shwpswd.state == 0) {
self.password.stringValue = self.visPswd.stringValue //Sync the two
self.password.isHidden = false // Inverse of above
self.visPswd.isHidden = true
}
}
Note the text fields password and visPswd are the same size and position in the view - one remains hidden at all times to avoid overlapping. When the user enters values in either the password or visPswd field, it syncs with the other field when the checkbox state is changed.
You can accomplish what you want adding a second text field in top of your secure field. Add an IBAction to your check box to switch your fields isHidden property and copy the other textField stringValue and make it the first responder. Your implementation should look like something like this:
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var password: NSSecureTextField!
#IBOutlet weak var showPassword: NSTextField!
#IBOutlet weak var shwpswd: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
shwpswd.state = .off
showPassword.isHidden = true
}
override func viewDidAppear() {
super.viewDidAppear()
password.window?.makeFirstResponder(password)
}
#IBAction func showHidePassword(_ sender: NSButton) {
showPassword.isHidden.toggle()
password.isHidden.toggle()
if !showPassword.isHidden {
showPassword.stringValue = password.stringValue
showPassword.becomeFirstResponder()
} else {
password.stringValue = showPassword.stringValue
password.becomeFirstResponder()
}
}
}
show/hide password sample

Variable in label Name - Swift

Is it possible to use a variable in a label name.
For example, my label is called button1text and I have a variable var x = 1.
Is there a way to do thisbutton(x)text?
No. You can not have variable name in identifier.
Variable names are evaluated at compile time, so no, it's not possible (at runtime).
Alternatively use an array or assign tags to the labels and get the label with viewWithTag
You can use reflection with Mirror. The capabilities are very limited in the context you want but you can try something like:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet weak var button3: UIButton!
#IBAction func didTapGoButton(_ sender: Any) {
let mirror = Mirror(reflecting: self)
for child in mirror.children {
if let v = child.label, v == "button2" {
(child.value as! UIButton).titleLabel?.text = "changed"
}
}
}
}

Displaying an Array of type Double on UILabel in Xcode

I am trying to make a basic shopping cart app where you can add an item to your cart, store the cost of the item in an array and then have the array displayed when you click "Receipt". However, every time I click "Receipt" on my app, the simulator crashes and displays
"Thread1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0)
beside my line of code that reads "allItems += item". If anyone has any ideas as to how I can my array of numbers displayed in a UILabel using a for in loop, please let me know. I will post source code below. Thanks in advance
class ViewController: UIViewController {
var priceOfApple = 1.75
var cart = [Double]()
var total = 0.00
#IBOutlet weak var appName: UILabel!
#IBOutlet weak var Balance: UILabel!
#IBOutlet weak var Instructions: UILabel!
#IBOutlet weak var redApple: UIButton!
#IBOutlet weak var appleInfo: UILabel!
#IBOutlet weak var addToCart: UIButton!
#IBOutlet weak var itemsPurchased: UILabel!
#IBAction func selectedApple(sender: AnyObject) {
Instructions.hidden = true
appleInfo.hidden = false
addToCart.hidden = false
}
#IBAction func purchaseApple(sender: AnyObject) {
cart.append(priceOfApple)
total += priceOfApple
Balance.text = "Balance : \(total)"
Instructions.hidden = false
appleInfo.hidden = true
addToCart.hidden = true
}
#IBAction func viewReceipt(sender: AnyObject) {
redApple.hidden = true
Instructions.hidden = true
itemsPurchased.hidden = false
for item in cart {
var allItems = Double(itemsPurchased.text!)!
allItems += item
allItems = Double(itemsPurchased.text!)!
}
}
}
If I understand correctly, this is what you should do:
First, create a variable outside the for-loop,
then inside the loop that variable will start storing every value in the array separated by " ". Once It is done, you can display its value in the Label.
var itemsInCart = ""
for items in cart{
itemsInCart += String(items) + " "
}
itemsPurchased.text = itemsInCart
I hope it helps!!!
A cleaner and safer way to do it:
let result = cart.flatMap { Double(itemsPurchased.text ?? String()) }.reduce(0: combine: +)
Doing that, you shouldn't get EXC_BAD_INSTRUCTION anymore, but you should still check if is the text convertible to a Double.

Textfield and floats in Swift

I have 2 textfields. If they both has a float value bigger than 100, when you click on my button it should allow you to go to another page.
So far so good, however in my code the text field can't have either int or float or doubles...
What can I do?
As Lukas says you need to convert it to a string. If you are capturing the value in the textfield on button click, you need to convert it, like so:
if let doubleValue = Double(textField.text!) {
}
I think based on what you have said, you need to do something like this:
class ViewController: UIViewController {
#IBOutlet weak var box1: UITextField!
#IBOutlet weak var box2: UITextField!
#IBOutlet weak var Check: UIButton!
#IBOutlet weak var Page1: UILabel!
#IBAction func didPressCheckButton(sender: UIButton) {
if let stringValue = box1.text {
if let doubleValue = Double(stringValue) {
if doubleValue > 100 {
print("Navigate to next page")
}
}
}
}
}
You will need to modify the check so that you check if both text boxes have values over 100, but this is a starting point.