String to int Button - ios

I'm working on a math multiple choice buttons based swift app. I want to check if the selected button is the correct answer. i have the following code.
let sum = num1.text!.toInt()! + num2.text!.toInt()!
if btn2.titleLabel! == "\(sum)"
{
check.text = "Right"
}
else
{
check.text = "Wrong"
}
it still doesn't work when I click on a answer choice. It says wrong for all

You are comparing the actual UILabel object to the sum and not the text of the label to the sum, so try:
let sum = num1.text!.toInt()! + num2.text!.toInt()!
if btn2.titleLabel!.text == "\(sum)"
{
check.text = "Right"
}
else {
check.text = "Wrong"
}

You should connect your buttons to an #IBAction function.
Keep the sum as an Int. No need to convert it to a String.
The function could look like this.
#IBAction func theButtons(sender: UIButton) {
let p = sender.currentTitle!.toInt()
if sum==p {
check.text = "right"
}
else{
check.text = "wrong"
}
}

Related

Detect when a button is pressed outside of the IBAction in Swift?

I'm a beginner programmer making my first real app, a calculator in Swift.
It's mostly working, but one issue I'm running into is how it displays numbers after pressing one of the operator buttons. Currently, whenever an operator button is pressed, I have it set the label at the top of the calculator to "0". But on actual calculators, this top display won't change until another number button is pressed.
If I don't reset the display to 0, then any number buttons that are pressed will add to the current text at the top, and mess up the equation that the calculator will have to do (i.e. 2+2 displays 22, and the solution it displays is 22+2=24)
I'm wondering if it's possible to detect when one of the number buttons is pressed (listed in my code as the intButtonPressed IBAction) outside of the intButtonPressed function? That way I can keep the top label the same until the user starts inputting more text, then I can set it to 0 to prevent the calculator from breaking.
Any other possible (better) solutions would be welcome as well
Here's my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var topLabel: UILabel!
var num1 = Double()
var solution = Double()
var op = String()
#IBAction func intButtonPressed(_ sender: UIButton) {
if topLabel.text == "0" {
topLabel.text = sender.currentTitle
}
else if topLabel.text == String(solution) {
num1 = Double(topLabel.text!)!
solution = 0.00
topLabel.text = sender.currentTitle
// Basically stops user from adding to solution?
// Also stores solution as num1 and clears solution field
}
else {
topLabel.text = topLabel.text! + sender.currentTitle!
// Keep typing
}
if (topLabel.text?.count)! > 12 {
topLabel.text = "Error"
}
else {
return
}
// if its greater than 12 characters, display "error"
}
#IBAction func clearButtonPressed(_ sender: UIButton) {
num1 = 0.00
solution = 0.00
topLabel.text = "0"
}
#IBAction func opButtonPressed(_ sender: UIButton) {
if sender.currentTitle == "=" {
equals()
}
else {
op = sender.currentTitle!
num1 = Double(topLabel.text!)!
topLabel.text = "0"
}
// Need it to display num1 until I press another button, then I need it to only display that text.
}
func equals() {
switch op {
case "+":
add()
case "-":
subtract()
case "×":
multiply()
case "÷":
divide()
default:
print(Error.self)
}
}
func add() {
solution = num1 + Double(topLabel.text!)!
topLabel.text = String(solution)
}
func subtract() {
solution = num1 - Double(topLabel.text!)!
topLabel.text = String(solution)
}
func multiply() {
print("topLabel = ", topLabel.text!)
solution = num1 * Double(topLabel.text!)!
print("solution = ", solution)
topLabel.text = String(solution)
}
func divide() {
solution = num1 / Double(topLabel.text!)!
//answer()
}
}
Update for anyone who finds this in the future: I've solved the issue, and realized that I wasn't very clear with what I wanted it to do. I solved the problem simply by adding a condition to the if/else statement in the inButtonPressed function that detects if the topLabel is 0. By rewriting that to detect if the topLabel is 0 OR the same as num1, and then changing the else statement in the opButtonPressed function to set topLabel to String(num1), the program does exactly what I want. Here's the rewritten code:
#IBAction func intButtonPressed(_ sender: UIButton) {
if topLabel.text == "0" || topLabel.text == "0.0" || topLabel.text == String(num1){
dotPressed = false
// Resets dotPressed whenever the top is 0 or num1 and an int button is pressed
topLabel.text = sender.currentTitle
}
else if topLabel.text == String(solution) {
num1 = Double(topLabel.text!)!
solution = 0.00
topLabel.text = sender.currentTitle
// Basically stops user from adding to solution?
// Also stores solution as num1 and clears solution field
}
else {
topLabel.text = topLabel.text! + sender.currentTitle!
}
}
#IBAction func opButtonPressed(_ sender: UIButton) {
if sender.currentTitle == "=" {
equals()
}
else {
op = sender.currentTitle!
num1 = Double(topLabel.text!)!
topLabel.text = String(num1)
}
// Successfully displays num1 until I press another button, then only displays that text.
I also added a separate function to handle decimals, and I had to update the code in there as well to keep that working.

refactor suggestion for my array iteration?

i feel like there is a more elegant way what i have done below.. Any suggestion ?
import Foundation
var bullet = ["aka","bz","cy"]
for i in bullet {
if i.contains("ka") {
let p = bullet.firstIndex(of: i)
bullet[p!]
}
}
If you want to get the first matching value, then you can use first, if you want to get it's index then, you can use firstIndex and if let is to safely unwrap an optional value.
var bullet = ["aka","bz","cy"]
if let value = bullet.first(where: { $0.contains("ka") }) {
print(value) //"aka"
}
if let index = bullet.firstIndex(where: { $0.contains("ka")}) {
print(index) //0
}
You can use filter(_:) along with contains(_:) like,
let arr = bullet.filter { $0.contains("ka") }
You can do it like this:
if let kaItem = bullet.first({ $0.contains(“ka”) }) {
myLabel.text = kaItem
} else {
myLabel.text = “asdfghj”
}
If you need to get the index and set the text, you can use firstIndex method:
if let kaItemIndex = bullet.firstIndex({ $0.contains(“ka”) }) {
myLabel.text = bullet[kaItemIndex]
} else {
myLabel.text = “asdfghj”
}

UITextField has trailing the whitespace after secureTextEntry toggle

I am trying to toggle the password text field, but I am facing a problem of white space at right side of text field.
//Eye button action.
#IBAction func btnEyePassword(sender: AnyObject)
{
//If password text is secure.
if (self.passrordText.secureTextEntry == true)
{
self.passrordText.secureTextEntry = false
}
else
{
self.passrordText.secureTextEntry = true
}
}
Swift 4 solution
func togglePasswordVisibility() {
password.isSecureTextEntry = !password.isSecureTextEntry
if let textRange = password.textRange(from: password.beginningOfDocument, to: password.endOfDocument) {
password.replace(textRange, withText: password.text!)
}
}
You don't need extra if statement for simple toggle isSecureTextEntry property, but you should replace text this way to force UITextField recalculate text width to avoid extra space.
UPDATE
Swift 4.2
Instead of
password.isSecureTextEntry = !password.isSecureTextEntry
you can do this
password.isSecureTextEntry.toggle()
Dont worry, in both cases when you print your textField.text your data will be same, there would not be white space.
Check with print(self.passrordText.text)
Declare var str : String = ""
#IBAction func btnEyePassword(sender: AnyObject)
{
//If password text is secure.
if (self.passrordText.secureTextEntry == true)
{
self.passrordText.secureTextEntry = false
self.passrordText.text = ""
self.passrordText.text = str
print(self.passrordText.text)
}
else
{
self.passrordText.secureTextEntry = true
str = self.passrordText.text!
print(self.passrordText.text)
}
}
This happens because of space consumption, "W" keeps much space while "i" keep lesser space.

Add a dot in Calculator Swift

I've tried implementing the dot or "point" in calculator I'm programming the windows 7 calculator as a reference to my calcu.
I've tried this in my code:
#IBAction func btnDot(sender: AnyObject) {
if(lblResult.text!.characters.count == 0) {
lblResult.text = "0."
}
else {
if(Float(lblResult.text!.lowercaseString.characters.contains(".")) == -1) {
lblResult.text = lblResult.text! + "."
}
}
lblResult.text = lblResult.text
}
but the function btnDot doesn't seem to work. What seems to be the problem here?
Note: The lblResult.text is the Id of my UILabel for the display of results
Try this code
if (lblResult.text?.characters.count == 0){
lblResult.text = "0."
}
else{
if lblResult.text!.rangeOfString(".") == nil{
lblResult.text = lblResult.text! + "."
}
}
If you want help you with your code you'll need to provide more info about the problem, now I just could give you a working example.

CS193P Assignment 1 π

I'm studying CS193P course on iTunesU. I have a question related to the 1st assignment - Programmable Calculator. I've attempted to add the π button as described in the lectures and the homework assignment. However, pressing the π key followed by enter or and operand causes a crash with the message: "fatal error: unexpectedly found nil while unwrapping an Optional value"
class CalculatorBrain
{
private enum Op {
case Operand(Double)
case NullaryOperation(String, () -> Double)
case UnaryOperation(String, Double -> Double)
case BinaryOperation(String, (Double,Double) -> Double)
var description: String{
get {
switch self {
case .Operand(let operand): return "\(operand)"
case .NullaryOperation(let symbol, _): return symbol
case .UnaryOperation(let symbol, _): return symbol
case .BinaryOperation(let symbol,_):return symbol
}
}
}
}
private var opStack = [Op]()
private var knownOps = [String:Op]() //initialize dictionary
init() {
func learnOp (op: Op) {
knownOps[op.description] = op
}
learnOp(Op.BinaryOperation("×", *))
learnOp(Op.BinaryOperation("÷", { $1 / $0 }))
learnOp(Op.BinaryOperation("+", +))
learnOp(Op.BinaryOperation("−", { $1 - $0 }))
learnOp(Op.UnaryOperation("√", sqrt))
learnOp(Op.UnaryOperation("sin", sin))
learnOp(Op.UnaryOperation("cos", cos))
learnOp(Op.NullaryOperation("π", { M_PI }))
}
I've been able to force it in the view controller, but know this is a hack:
var displayValue: Double{
get{
// I don't understand why I had to put this hack in for π
// if (calcDisplay.text != "π"){
return NSNumberFormatter().numberFromString(calcDisplay.text!)!.doubleValue
// } else {
// return M_PI
// }
}
set{
calcDisplay.text = "\(newValue)"
userIsInTheMiddleOfTyping = false
}
}
I'm new to Swift / Obj-C. Can someone please help point me in the right direction to resolve this?
Full source: https://github.com/philnewman/Calculator
#IBAction func appendPi(sender: UIButton) {
let x = M_PI
if userIsInTheMiddleOfTypingANumber {
displayValue = x
display.text = "\(displayValue)"
}else {
displayValue = x
userIsInTheMiddleOfTypingANumber = true
enter()
}
}
Created a new UIButton function for PI separate from the other functions. Working for me, give it a go.
NSNumberFormatter().numberFromString is designed to convert numerical strings into numbers. A "numerical string" is a string whose contents are of the form:
([:digit:]+(\.[:digit:]*)?)|(\.[:digit:]+)
Where [:digit:] is the set of digits {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}.
Essentially, it will only parse numbers from strings whose characters are within 0-9 and an optional ..
Because π doesn't belong to this set of 10 characters, it is rejected and the NSNumberFormatter is unable to parse a number from the string.
I am doing the same course, but as I am not yet at the point of separating my MVC (will do that in the next assignment), I can only give you a hint where you go wrong. As it works for me....
Your hack is testing calcDisplay.text as being "π", however at that moment calcDisplay.text should already be 3,14159.
That is what I checked with a println on my working assignment.
So I can show you part of my code which is not optimal for MVC yet:
case "cos": performOperation{cos($0)}
case "∏": performConstant(operation)
func performOperation (operation: (Double) -> Double) {
if operandStack.count >= 1 {
displayValue = operation(operandStack.removeLast())
enter()
}
}
func performConstant (symbol: (String)) {
switch symbol {
case "∏": displayValue = M_PI
default: break
}
display.text = "\(displayValue)"
enter()
}
I think it can be more optimal too, but it might help you with finding the bug in your code.
I am also doing same course. I did solved "." and "pie" question. See if this help you.
#IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if digit == "." {
if (display.text!.rangeOfString(".") == nil) {
display.text = display.text! + "."
} else {
//Don't display anything
}
} else if digit == "∏" {
displayValue = pie
} else {
if userIsInTheMiddleOfTypingANumber {
display.text = display.text! + digit
} else {
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}
}
}

Resources