Swift 4 adding a label.text int to a button int [duplicate] - swift

This question already has answers here:
Converting String to Int with Swift
(31 answers)
Closed 5 years ago.
I currently have a label that displays the value of a database read. The database has the value as a string. Through viewWillAppear, the database is read and will display the correct value in the label. I also have a button that when pressed, should add 1 to the current label value. When the label value changes, it will send the current value to the database to store.
I have the label displaying correctly. I was able to add a 1 to the label but it added it onto the end of the number instead of adding the two together (ie. the value was 6, button pressed, value is now 61). The database read/write portion is working correctly. The only thing I cannot seem to understand is how to add the two numbers together. It seems like such a simple process but everything that I have tried does not work. Any help is greatly appreciated!
One example of code that I have used:
class ViewController: UIViewController {
#IBOutlet weak var label: UILabel!
var variable = String([])
#IBAction func addOnePressed(_ sender: UIButton) {
var variable = Int(label.text!)!
let number = 1
if let result = variable += number { self.label.text = result }

The main issue is that the property variable is not equal to the local variable variable
I recommend to declare the property variable as Int, set the label in viewDidLoad and increment the property in addOnePressed
class ViewController: UIViewController {
#IBOutlet weak var label: UILabel!
var variable = 0
override func viewDidLoad() {
super.viewDidLoad()
self.label.text = "\(variable)"
}
#IBAction func addOnePressed(_ sender: UIButton) {
variable += 1
self.label.text = "\(variable)"
}
}
PS: The syntax String([]) is confusing. Actually it's simply an empty string ""

Related

How do I programatically move the cursor from one NSTextField to another after a character count has been reached?

I'm trying to create a window where the user can enter the activation key for the product and I've done so by creating 5 different NSTextField's, as shown in the image.
What I want to add to this is the ability for the cursor to move to the next text field once a character count has been reached (which is 5 characters maximum per textfield).
I did find code for this but it was for IOS and didn't work since i didn't know what changes to make (Code for the IOS version)
here's the code I tried
override func viewDidLoad() {
super.viewDidLoad()
ActKeyOne.textDidChange(Notification.Name.init(rawValue: "textchanged"))
}
it gave the error:
Cannot convert value of type 'Notification.Name' (aka 'NSNotification.Name') to expected argument type 'Notification'
The answer to part of this this question was posted here by #cheesey
here is the complete code to create a window that takes the license key for a product from a user (This is using swift 4).
First set the Text Fields as the delegates and first responders in the viewDidLoad Function and then change the first responder once the string limit is hit
class CommercialActivationView: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
#IBOutlet weak var firsttextfield: NSTextField!
#IBOutlet weak var secondtextfield: NSTextField!
#IBOutlet weak var thirdtextfield: NSTextField!
firsttextfield.window?.makeFirstResponder(firsttextfield)
firsttextfield.delegate = self
}
func makeFirstResponder() {
if firsttextfield.stringValue.count == 5 {
firsttextfield.window?.makeFirstResponder(secondtextfield)
}
if secondtextfield.stringValue.count == 5 {
secondtextfield.window?.makeFirstResponder(thirdtextfield)
}
}
}
Now to create the extension that creates the character limit or the text field every time the user edits the TextField (Here i'm limiting the number of characters per text field to 5).
extension CommercialActivationView: NSTextFieldDelegate {
func controlTextDidChange(_ obj: Notification) {
let object = obj.object as! NSTextField
if object.stringValue.count > 5{
object.stringValue = String(object.stringValue.dropLast())
makeFirstResponder()
}
}
This works such that once 5 characters are reached in 1 TextField it switches to the next one automatically. Also the code I've posted is for 3 TextFields more text fields can be add if needed.

Force Unwrap Optionals from UITextfield

I'm trying to get a value from a UITextfield and it's being returned as optional. I've tried suggested methods of force unwrapping and I'm still receiving Optional("WhateverUserInputHere") instead of 'WhateverUserInputHere'. I've also been looking for a way to make sure the textfield is not empty before retrieving the value, to keep from crashing when force unwrapping. As of now, the value is retrieved after the user hits a button to move to the next screen, and this button is only enabled once the user begins to edit the textfield. If they decide to delete everything within the textfield, however, they can still move forward. Any way to prevent this/make sure button is only enabled once user has finished typing and textfield is not empty?
// Variable used to store value from textfield
var nametemp:String?
var name:String = ""
#IBOutlet weak var NameInput: UITextField!
#IBOutlet weak var NextButton: UIButton!
#IBOutlet weak var TestLabel: UILabel!
// Enables button when textfield has been edited
#IBAction func NameInputEditingDidChange(_ sender: Any) {
NextButton.isEnabled = true
}
// When button is used, value of textfield is retrieved
#IBAction func NextButtonVariableTest(_ sender: Any) {
nametemp = String(describing: NameInput.text)
name = nametemp!
// Label returns optional value
TestLabel.text = "Hello" + name
}
}
Simply use
self.name = NameInput.text!
or
self.name = NameInput.text ?? ""
Once you use String(describing:) the Optional(...) text will be part of your string rather than an optional string and you won't be able to remove it.

Need help getting swift app to display reverse string on label correctly

I'm a novice and i'm practicing by making an app that takes a string through a text box and on a button click displays the string, reversed, on a label. I'm pretty sure i have the part about reversing the string correct, but i'm not exactly sure where i'm going wrong because i'm getting two errors.
one is "Argument to #IBAction method cannot have non-object type 'String'
the other "Cannot assign value to type 'ReversedCollection to type 'String?'
I'm not sure what i'm doing wrong since i haven't grasped the concept of taking a function by button action and having what is returned display on a label 100%. Help would be greatly appreciated.
Heres the code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var input1 : UITextField!
#IBOutlet var label : UILabel!
#IBAction func reverse(_ input1: String){
let output = input1.characters.reversed()
label.text = String(output)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
I assume your reverse func is hooked up to the button's touch-up-inside, and you created it by Ctrl-dragging from the button to code. This would have created the correct parameter, which you then changed to have type String. When the button is touched, the parameter it sends is the button itself (eg. as sender: AnyObject).
You should change the function back to what it was originally, and then change your code to:
let output = input1.text.characters.reversed()

Set maximum characters (to one) in a NSTextfield in Swift

How do i set the maximum amount of characters in multiple NSTextfields (OSX cocoa app, NOT iOS) to one in Swift?
Please explain how to do it, because I'm a complete newbie when it comes to OSX app development and therefore I don't understand short answers like "Use NSFormatter", because I have no idea what it is and how to implement it. Like Examples
There's no built-in way to simply set the maximum, I think because you need to decide what behavior you want. For example, if there's already one character in the field, and the user enters a second character, what should happen? Should the 2nd character be ignored? Replace the first? Beep?
In any case, you can get whatever behavior you want using the NSText Delegate methods. Make your view controller (or whatever object has the logic) a delegate of the text field, and implement the various delegate method(s) to do what you need.
Again, the exact behavior is up to you, but if I were implementing this, I might be inclined to make the text field always use the last character entered (such that, if one character is already present, pressing a second replaces the first). To do that, you'd want to override textDidChange to look at the value of the text field, and modify it if appropriate. Something like:
class ViewController: NSViewController, NSTextFieldDelegate {
#IBOutlet weak var textField: NSTextField!
override func controlTextDidChange(obj: NSNotification) {
if self.textField.stringValue.characters.count > 1 {
self.textField.stringValue = String(self.textField.stringValue.characters.last!)
}
}
}
You don't need to limit the characters a user will enter just only look at the first character entered. In fact, it is probably better since you will always have to handle possible user errors. If you want to you can issue an alert that they entered too many by getting the characters.count. You might want an alert if they don't answer at all. The code below will work as is if you set up a storyboard with 1 NSTextField and one button and connect them. If you have more than one textfield, i.e. like a multiple choice test, just set up all the text fields the same way.
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var firstLetter: NSTextField!
Add as many text fields as you need:
#IBOutlet weak var secondLetter: NSTextField!
#IBOutlet weak var thirdLetter: NSTextField!
etc.
#IBAction func button(sender: AnyObject) {
var firstEntry = firstLetter!.stringValue
var index1 = firstEntry.startIndex
if firstEntry.characters.count > 1 {
runMyAlert("Bad USER! ONLY ONE Character!")
}
if firstEntry == "" { //left it blank
runMyAlert("You need to enter at least one character!")
exit(0) //or you'll crash on next line
}
var nameLetter1:Character = firstEntry[index1]
print( "First Letter == \(nameLetter1) ")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
func runMyAlert( alertMessage: String){
var myWindow = NSWindow.self
let alert = NSAlert()
alert.messageText = "ERROR ERROR ERROR"
alert.addButtonWithTitle("OK")
alert.informativeText = alertMessage
alert.runModal()
}
}

Assigning text field value to variable in Swift

I am trying to learn Swift and it is turning out to be more different from other languages than I expected...
I just want to store the value of a user's input as an integer in a variable.
My attempts result in the following error:
"fatal error: unexpectedly found nil while unwrapping an Optional value"
I have tried this multiple ways and can't seem to come up with a solution, I know there must a simple way to do this.
var intNumber: Int = 0
#IBOutlet weak var txt_Number: UITextField!
for view in self.view.subviews as [UIView]{
if let txt = view as? UITextField
{
if let txtData = txt.text where txtData.isEmpty
{
// Error Message
}
else
{
intNumber = Int(txt_Number.text)
}
}
}
I know the above code isn't correct, but I think that's the closest to correct I have come. I seem to be missing something as far as unwrapping goes. I understand the principal of unwrapping, but nothing I have tried will compile, or if it does compile then it fails with the error above when the code is initiated (code is initiated when a button is pressed).
Thank you in advanced for any help!
A couple of thoughts:
Make sure your outlet is hooked up to txt_Number. All of that code checking to make sure it's not nil is not necessary if (a) it's an outlet you hooked up in IB; and (b) you're not doing the above code before the view is completely loaded (i.e. viewDidLoad was called).
If the outlet is not hooked up, you'll see an empty dot on the left margin:
If it is hooked up correctly, you'll see a filled in dot on the left margin:
If everything is hooked up correctly, you can just do:
guard let txtData = txt_Number.text, let value = Int(txtData) else {
// report error and then `return`
return
}
intNumber = value
If you want to get fancy, you might want to ensure the user only enters numeric values by
In viewDidLoad, specify that the keyboard is for decimal numbers only.
txt_Number.keyboardType = .NumberPad
Or you can specify this in IB, too.
Specify a delegate for the text field and only allow them to enter numeric values. (This might seem redundant based upon the prior point, but it's not, because you have to also anticipate them pasting in a string to the text field.)
See https://stackoverflow.com/a/26940387/1271826.
For starters, you don't have to iterate over subviews if you have direct reference txt_Number, but this is not an essence of your question.
if let semantics will let you unwrap any optional inside {} brackets, so the most visible solution here is to:
if let unwrappedString = txt_Number.text {
if let unwrappedIntegerInit = Int(unwrappedString) {
intNumber = unwrappedIntegerInit
}
}
My full example from playgrounds:
var intNumber: Int = 0
var txt_Number: UITextField = UITextField()
txt_Number.text = "12"
if let unwrappedString = txt_Number.text {
if let unwrappedIntegerInit = Int(unwrappedString) {
intNumber = unwrappedIntegerInit
}
}
print(intNumber)
Or you can use guard inside a function:
func parse() {
guard let text = txt_Number.text, let number = Int(text) else { return } // no text
intNumber = number
}
TIP:
You have to unwrap txt_Number.text and Int(text) separately cause Int(text) has to have nonoptional argument.
Did you try with this?
if let txtData = txt.text where !txtData.isEmpty
{
intNumber = Int(txtData)
}
else
{
// Error Message
}
ADD:
Int() function returns an Optional. If you are sure that the value is correct, you can force the unwrapping by using ! at the end of the variable name (when you are using it), otherwise just put the question mark ?
tried below code to assign value of TextField to variable of float type and all bug disappear like magic
#IBOutlet weak var txtamount: UITextField!
#IBOutlet weak var txtrate: UITextField!
#IBOutlet weak var txtyear: UITextField!
#IBOutlet weak var lblresult: UILabel!
#IBAction func btncalculate(_ sender: UIButton)
{
print("button is clicked")
var amount,rate,year,answer : Float
amount = Float(txtamount.text!)!
rate = Float(txtrate.text!)!
year = Float(txtyear.text!)!
answer = (amount * rate * year) / 100.0
}