using switch statement inside a button - swift

Please help and I'm sorry if this is covered somewhere else although i have looked elsewhere and whilst there are answers to my topic i cannot find one for my problem. so if anyone could help that would be great.
basically i am trying to do a switch statement inside a button so that when i click the button the statement activates in my label, but for some reason i cannot get it to work
here is my code below
when i hit run it always shows the "This is an even number between 0 and 10" regardless of even number, odd number or large number
Any help would be greatly appreciated
thank you very much

Right before the switch line you have to add three lines to assign the value of the input text field to the variable number.
guard let inputText = numberInput.text, let input = Int(inputText) else {
numberOutput.text = "Please enter a number!"
return }
number = input

This code works fine in playground, always prints expected output.
var number = 6
switch number {
case 0,2,4,6,8,10:
print("even")
case 1,3,5,7,9:
print("odd")
default:
print("higher")
}
where are you changing the number variable? Are you doing it on one of the callback methods for textfield delegate?

you are not changing the value of your var number. Looks like it is always 6 based from your code

You can simply do this:
import UIKit
class EmptyViewController: UIViewController
{
#IBOutlet weak var label: UILabel!
#IBOutlet weak var textField: UITextField!
#IBAction func buttonHit(_ sender: UIButton)
{
if let text = textField.text, let number = Int(text)
{
switch number {
case 0,2,4,6,8,10:
label.text = "Even"
case 1,3,5,7,9:
label.text = "Odd"
default:
label.text = "Higher"
}
}
else
{
label.text = "Please enter a valid number"
}
}
}

Related

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

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 ""

cs193p Swift - key value coding error

I can't believe I'm having a problem with the very first lecture! We are building a calculator (it is not at all functional as a calculator at this point). Mine was working just fine until the performOperation function was added. Now I'm getting "this class is not key value coding compliant" error. The thing is that, as far as I can see, my code EXACTLY replicates the code that he is using in the class. I must be missing something but I've checked roughly 50 times to find a difference and I can't find one. Help? It is crashing every time.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var display: UILabel!
var userIsInTheMiddleOfTyping = false
#IBAction func touchDigit(sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTyping {
let textCurrentlyInDisplay = display.text!
display.text = textCurrentlyInDisplay + digit
} else {
display.text = digit
}
userIsInTheMiddleOfTyping = true
}
#IBAction func performOperation(sender: UIButton) {
userIsInTheMiddleOfTyping = false
if let mathematicalSymbol = sender.currentTitle {
if mathematicalSymbol == "π" {
display.text = String(M_PI)
}
}
}
}
EDIT: Code format
You can check your viewcontroller in storyboard, at the Module TextField in the right toolbar.
Do following steps if module textfield
is empty (there’s no placeholder):
Step 1. Focus Module TextField
Step 2. Edit randomly then clear
Step 3. Press Enter, if the result is as same as this picture, everything’s going okey.

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
}

How do I validate IBOutlet/var for nil?

I've written a simple application using Swift and Xcode 6.1.1. The program, which is a simple calculator, works well but I haven't been able to validate non-nil input for the three text fields. As a result, if the user leaves the field blank and then hits "calculate," the application crashes.
The app takes three inputs, initially as strings. I wrote an if statement to check for nil but it doesn't work - it will just pass to else regardless. Here's the code block that's relevant to my question:
...
#IBOutlet var calcButton: UIBarButtonItem!
#IBOutlet var yearOneField: UITextField!
#IBOutlet var yearTwoField: UITextField!
#IBOutlet var yearThreeField: UITextField!
#IBOutlet var displayWindow: UILabel!
#IBAction func calcButtonTapped(sender: AnyObject) {
if (yearOneField == nil) {
displayWindow.text = ("Non-zero entries are not permitted. Please enter new values.")
} else {
let yearOne = yearOneField.text.toInt()
let yearTwo = yearTwoField.text.toInt()
let yearThree = yearThreeField.text.toInt()
...
I was thinking I could evaluate the IBOutlet for nil but that didn't work. I'm new to Swift and Xcode so I hope this is a n00b question to the more experienced developers out there. Thank you.
The only way the #IBOutlets could be nil is if you forgot to wire them up in Interface Builder. Usually you don't need to check that because the crash will tell you to fix that problem.
The toInt() function returns an Optional Int (aka Int?) that must be unwrapped before being used. toInt() will return nil if the value in the text field does not represent a valid Int. "2.1", "seven", and "" would all return nil if converted with toInt(). I recommend you use optional binding (if let) syntax to check the conversion for nil and unwrap the result if it is not nil:
if let yearOne = yearOneField.text.toInt() {
if let yearTwo = yearTwoField.text.toInt() {
if let yearThree = yearThreeField.text.toInt() {
// yearOne, yearTwo, and yearThree are all valid Ints
// so do the calculations
}
}
}
Alternatively, if you know you want to use a default value (like 0) when the field can't be converted to an Int, you can unwrap the result using the nil coalescing operator ?? like so:
let yearOne = yearOneField.text.toInt() ?? 0
let yearTwo = yearTwoField.text.toInt() ?? 0
let yearThree = yearThreeField.text.toInt() ?? 0
The text fields themselves will never be nil. They are created and assigned during initialization, and you're never removing them.
I think you want to check if their text properties contain any text, which you can do like this:
Updated for Swift 2:
if let text = yearOneField.text where !text.isEmpty {
// perform the conversions
} else {
// the text field is empty
}
You can avoid nesting using guard:
guard let text = yearOneField.text where !text.isEmpty else {
// the text field is empty
return
}
// perform the conversions
I prefer the guard syntax because it's clearer about what the ideal result is.
You can just check as you do with normal optionals.
guard let unwrapped = myLabel else {return}
Or like this
if myLabel == nil {
//do stuff
}
Or like this:
if let unwrappedLabel = myLabel {
}