[Swift 1] Day 2 - Code Exercise Solution


#42

Hi,

as we use the “,” instead of the “.” I first try to find the “,” and replace it by an “.”. Then the calculation should work also with my “German” device…

jvc

    let widthstring = widthTextField.text.stringByReplacingOccurrencesOfString(",", withString: ".", options: nil, range: nil)
    let heightstring = heightTextField.text.stringByReplacingOccurrencesOfString(",", withString: ".", options: nil, range: nil)

    let width = NSString(string: widthstring).doubleValue
    let height = NSString(string: heightstring).doubleValue
    
    let area = width * height
    outputLabel.text = "\(area)"

#43

Hi guys,
This is my first post in this forum. This is my solution.

class ViewController: UIViewController {

    @IBOutlet weak var hightTextField: UITextField!
    @IBOutlet weak var widthTextField: UITextField!
    @IBOutlet weak var outputResult: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func buttonPressed(sender: AnyObject) {
        
        if let hight = hightTextField.text.toInt() {
            var higthDouble = Double(hight)
            if let width = widthTextField.text.toInt() {
                var widthDouble = Double(width)
                var area = higthDouble * widthDouble
                outputResult.text = "\(area)"
                
            }
            else {
                // wring width
                println("wrong width")
                outputResult.text = "Enter a valid Width"
            }
            
        }
        else {
            println("wrong")
            outputResult.text = "Enter a valid Hieght"
        }
    }
}

#44

Get some problems

.toDouble() I don’t have…
.doubleValue gives me 0.0 from String without number!!

but after I read all post I found code that is working for me
(Thank you guys for help!)

button code:

@IBAction func calculateButtonPressed(sender: AnyObject) {
    println("calculateButtonPressed")

    var widthA = NSNumberFormatter().numberFromString(widthTextField.text)
    var heightA = NSNumberFormatter().numberFromString(heightTextField.text)
    //checking NSNumber result
    println(widthA)
    println(heightA)
    
    if let width = NSNumberFormatter().numberFromString(widthTextField.text){
        if let height = NSNumberFormatter().numberFromString(heightTextField.text){
            println("Valid input! \(width) x \(height)")
            
            var area = Double(width) * Double(height)
            outputLabel.text = "\(area)" //String(area)
        }else{
            outputLabel.text = "Not valid inputs!!"
        }
        
    }else{
        outputLabel.text = "Not valid inputs!!"
    }
}

Only I wonder why in - var area = Double(with) * Double(width) -
Double is able to unwrap optional? The - with! - was not working…


#45

You are already performing a validity check with the code above, so there is no need of optionals.
This guarantees you that the value is not only nil, but can be converted.


#46

Hi

Ok then why

var area = width * height
is not working?

I have to use
var area = Double(width) * Double(height)

By the way
var widthA = NSNumberFormatter().numberFromString(widthTextField.text)
var heightA = NSNumberFormatter().numberFromString(heightTextField.text)
//checking NSNumber result
println(widthA) - gives on my Xcode optional result
println(heightA)-gives on my Xcode optional result

if let width = NSNumberFormatter().numberFromString(widthTextField.text){
if let height = NSNumberFormatter().numberFromString(heightTextField.text){
on my Xcode only with optional results

Please check with your Xcode

I don’t understand that…
Thanks


#47

You still have to convert to Double first.
Please check Apple documentation here:

https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/index.html

NSNumberFormatter().numberFromString returns an optional NSNumber, which doesn’t have a type.
Therefore you need to converted to Double, Float or something else and check if it’s ‘nil’ before you can use it.


#48

Thank you very much!

Now I get it…

Thanks


#49

Sorry now again…

Just when I was thinking that I get it…

I wanted to use NSNumberFormatter().numberFromString in TipCalculator

class ViewController: UIViewController {

@IBOutlet weak var amountText: UITextField!
@IBOutlet weak var tip10: UILabel!
@IBOutlet weak var tip15: UILabel!
@IBOutlet weak var tip20: UILabel!
@IBOutlet weak var tip5: UILabel!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
@IBAction func calculateButtonPressed(sender: AnyObject) {
    println("Tip")
    
    var amount = (amountText.text as NSString).doubleValue
    println("Text printed \(amount)")
    
    var tip10pro = amount * 0.1
    var tip15pro = amount * 0.15
    var tip20pro = amount * 0.2
    
    
    
    tip10.text = "$" + tip10pro.description
    tip15.text = "$\(tip15pro)"
    
    
    //Formatting number
    let numberFormatter = NSNumberFormatter()
    numberFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
    tip20.text = numberFormatter.stringFromNumber(tip20pro)
    
    //all by Formatting
    let tip5pro = NSNumberFormatter().numberFromString(amountText.text)
    tip5.text = " \(Double(tip5pro!) * 0.05)"
}
}

Please look on last part
let tip5pro

and last line is!!
tip5.text = " (Double(tip5pro!) * 0.05)"

Double was not enough to unwrap it?
Why?

In previous code for AreaCalculator Double was enough…
What is going on with that Formatting?!


#50

Here is what I did for you:

Look at the Playground I created, it should clear some things up for you:

Make sure you use ‘if let’ when you introduce NSNumberFormatter to check for nil or instead you can do that on a separate line : 'if tip5pro != nil … ’

Your tip5.text is still an optional because you can’t guarantee it’s not nil.
If you want to take the risk and say that it will never be nil you can force-unwrap it with the ‘!’ mark:


#51

Thank you ravenshore!!

Now I got it - I hope

Thank you for all help
Amazing


#52

You’ll definitely want to check that it’s not nil before using it. Otherwise your app can crash when that is nil

Something like:

if let amountString = amountText.text {
    if let tip = NSNumberFormater().numberFromString(amountString) {
        // do something with the tip (as a NSNumber)
       var decimalTip = tip.doubleValue  // use the methods for NSNumber
    }
}

This prevents crashes from user input – which would be a very bad user experience in your apps (i.e.: 1 star reviews).


#53
var width = (widthTextField as NSString).doubleValue
var height = (heightTextField as NSString).doubleValue
var area = width * height
var parameter = 2 * ( width + height )
outputLabel.text = "\(area)"
parimeterLabel.text = "\(parimeter)"

#54

class ViewController: UIViewController {

@IBOutlet weak var widthTextField: UITextField!
@IBOutlet weak var heightTextField: UITextField!
@IBOutlet weak var outputLabel: UILabel!
@IBOutlet weak var perimeterLabel: UILabel!


@IBAction func buttonPressed(sender: AnyObject) {

    println("Button Pressed")
    
    var doubleWidth = (widthTextField.text as NSString).doubleValue
    var doubleHeight = (heightTextField.text as NSString).doubleValue
    
    println("Valid input! \(doubleWidth) x \(doubleHeight)")
    
    var area = doubleWidth * doubleHeight
    var perimeter = 2 * area
    
    outputLabel.text = "\(area)"
    perimeterLabel.text = "\(perimeter)"
}

}

Questions:
What does int mean? Integer, whole numbers without decimals, 1,2, 4, 8, 16, etc.
What does String mean? String can be any text consisiting of chars, numbers, symbols, etc… Ex. January 1, 1999 , I read above post saying String in swift also accept emojis :smile:(makes sense since we’re developing on apps)


#55

//
// ViewController.swift
// Area Calculator 2
//
// Created by taha yassine hammi on 5/7/15.
// Copyright © 2015 Tyham. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var widthTextField: UITextField!
@IBOutlet weak var heightTextField: UITextField!


@IBOutlet weak var areaOutputLabel: UILabel!
@IBOutlet weak var perimetreOutputLabel: UILabel!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func areaButtonPressed(sender: AnyObject) {
    
    println("button pressed")

// if let width = widthTextField.text.toInt() {
// if let height = heightTextField.text.toInt() {

        let height = (heightTextField.text as NSString).doubleValue
        let width = (widthTextField.text as NSString).doubleValue
   
            println("Valid input! \(width) x \(height)")
            
        var area = width * height
        areaOutputLabel.text = "\(area)"

// }
// }

}

@IBAction func perimetreButtonPressed(sender: AnyObject) {
    
    let height = (heightTextField.text as NSString).doubleValue
    let width = (widthTextField.text as NSString).doubleValue

    var perimetre = 2 * (width + height)
    perimetreOutputLabel.text = "\(perimetre)"
    
}

}


#56

My Area Calculator with a bonus. I solved some issues by myself, which means they are not solved in the best way. But I tried. Any advice is appreciated :slight_smile: Thanks and good luck everyone.

Answers to Q :
Int means integer, a whole number without decimal places
String is set of numbers and letters, example : Porsche 911

Area Calculator on my Dropbox


#57

Int = number that can be written without a fractional component

String = an ordered collection of characters

birthdayString = [“August”, “Twenty Eighth”, “Two Thousand Fifteen”]

import UIKit

class ViewController: UIViewController {

// Input text fields
@IBOutlet weak var widthTextField: UITextField!
@IBOutlet weak var heightTextField: UITextField!

//Output text fields
@IBOutlet weak var outputLabel: UILabel!
@IBOutlet weak var outputPerimeterLabel: UILabel!

// Do any additional setup after loading the view, typically from a nib.
override func viewDidLoad() {
    super.viewDidLoad()
    
}

// Dispose of any resources that can be recreated.
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

// Button pressed
@IBAction func buttonPressed(sender: AnyObject) {

    println("button pressed")
    
            //Convert int to double
            var width = (widthTextField.text as NSString).doubleValue
            var height = (heightTextField.text as NSString).doubleValue
    
            // Area input
            println("Valid input! \(width) x \(height)")
    
            // Calculate area
            var area = width * height
    
            // Calculate perimeter
            var perimeter = 2 * (width + height)
    
            // Output results
            outputLabel.text = "\(area)"
            outputPerimeterLabel.text = "\(perimeter)"
            
   }
        
}

#58

This was my code for day 2. I like this extension method. Makes for very similar code.

Doug

extension String {
func toDouble() -> Double? {
return NSNumberFormatter().numberFromString(self)?.doubleValue
}
}

class ViewController: UIViewController {

@IBOutlet weak var widthTextField: UITextField!
@IBOutlet weak var heightTextField: UITextField!

@IBOutlet weak var outputLabel: UILabel!
@IBOutlet weak var perimeterLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func buttonPressed(sender: AnyObject ) {
    println("buttonPressed")

    if let width = widthTextField.text.toDouble() {
        if let height = heightTextField.text.toDouble() {
            println("Valid input \(width) x \(height)")
            
            var area = width * height
            var perimeter = 2 * width + 2 * height
            outputLabel.text = "\(area)"
            perimeterLabel.text = "\(perimeter)"
        }
    }

}

}


#59

This is my code for Day 2 Lesson. I like the idea that Ryan did. So, I tried to adapt the code with If-else statement. I found 2 problem issues. First, I have to convert Double to CGFloat for UIImageView.frame.size.width and UIImageView.frame.size.height. I found the solution in stackoverflow by using extension. Second, when I click on calculate button after change the number in textField box at third time UIImageView not have any change in size. I think this issue would come from if-else statement I tried to fix this but still not found the solution. Any comment or suggestion? Thanks.

import UIKit
// Adds extension to String
extension String {
   func toDouble() -> Double? {
       return NSNumberFormatter().numberFromString(self)?.doubleValue}
}

// Add extension convert to CGFloat
extension Double {
   var doubleToCGFloat: CGFloat { return CGFloat(self) }
}


class ViewController: UIViewController 
{

   @IBOutlet weak var widthTextField: UITextField!
   @IBOutlet weak var heightTextField: UITextField!

   @IBOutlet weak var areaOutput: UILabel!
   @IBOutlet weak var perimeterOutput: UILabel!

   var sizeRectangle: UIImageView!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
   super.didReceiveMemoryWarning()
   // Dispose of any resources that can be recreated.
}

@IBAction func buttonPressed(sender: AnyObject) {

   println("button pressed")

   if let width = widthTextField.text.toDouble() {
       if let height = heightTextField.text.toDouble() {

           println("Valid input! \(width) x \(height)")

           var area = width * height
           var perimeter = 2 * (width + height)

           sizeRectangle = UIImageView()
           var overSize = UILabel()

           if (width <= 350.0 && height <= 350.0) {

               overSize.text = ""
               overSize.backgroundColor = UIColor.whiteColor()
               sizeRectangle.backgroundColor = UIColor.redColor()
               sizeRectangle.frame.size.width = width.doubleToCGFloat
               sizeRectangle.frame.size.height = height.doubleToCGFloat
               sizeRectangle.center = CGPoint(x: view.frame.width/2, y: view.frame.height - (perimeterOutput.frame.origin.y - 10))
               view.addSubview(sizeRectangle)


               areaOutput.text = "Area = " + String(stringInterpolationSegment: area)
               perimeterOutput.text = "Perimeter = " + String(stringInterpolationSegment: perimeter)
           }
           else if (width > 350.0 || height > 350.0) {

               sizeRectangle.backgroundColor = UIColor.whiteColor()
               overSize.text = "Over 350 Points, is not a valid number!"
               overSize.font = UIFont.systemFontOfSize(18)
               overSize.backgroundColor = UIColor.yellowColor()
               overSize.sizeToFit()
               overSize.center = CGPoint(x: view.frame.width/2, y: view.frame.height/2)
               view.addSubview(overSize)
        }
      }
    }
  }
}

#60

add more println statements to track exactly what is happening in the if statements.


#61

Okay, thanks for your help.