[Swift 1] Day 5 - Code Exercise Solution


#1

What Weather app did you try to make?

Share your code


#2

Here is my weather app interface: iphone 5, 6 and ipad

What I was able to do:

  • made a mockup in Photoshop and put it as a temporary background image to speed up the layout process in xcode. Much easier to align everything and set text size when you have a jpg below.
  • Set all contrains for iphone 5, 6 and iPad in portrait mode only. almost there for landscape mode but couldn’t figure out how to resize item based on screen size. i don’t know if it’s possible.
  • background image stretch on all these devices (portrait mode). lots of bugs in xcode… Even if I sent the image to back (Arrange> Sent to back) it kept coming on top layer always when I run the app… had to send it to front and back again to see the UI elements. So I figured best way to do it in put bkg guide first, place UI elements, then delete bkg image to set contrains, and put final bkg image at the end only.

What I wasn’t able to do

  • background image doesn’t stretch on ipad landscape mode. Couldn’t figure out how to do it… Image is 1024 x 768. I tried with a bigger and larger one but it didn’t make any difference in landscape mode. my image view is set to Scale to Fill. tried all the others without success.
  • some elements are overlapping on iphone 5 landscape mode . I misses media queries and css… is there a way to adapt layout also based on screen size for some elements? seems natural to position some elements more horizontally on landscape mode but I didn’t find any solution.

#3

Beautiful. :heart_eyes:


#4

Thanks :slight_smile: by far the easiest exercice for me!


#5

Here is the screen.
I had many problems with constraints, I finally put the image and labels together inside a View. This is correct?
I tried on all devices and looks good.

The “View Controller Scene”


#6
  1. Make a for loop to countdown from 5 to 0 for a space shuttle launch.

Tip: Use sleep(1) to pause for 1 second.

for var countDown = 5; countDown <= 0; countDown-- {
println(countDown)
sleep(1)
}

  1. Given a list of photo filenames and a Picture folder, construct a new array of Strings with the full path to each file.

var photoNameArray = [“Apple.png”, “Mexico.png”, “Owl.png”]
var photoPath = "~/Pictures"
var photosToUpload: [String] = []

for fileName in photoNameArray{
photosToUpload.append("(photoPath)/(fileName)")
}

My Weather App:


#7

That’s what the size classes are for, though I haven’t tried them out yet. I assume you can somehow copy the whole layout to the landscape size class and then just adjust it. Has anyone done this?


#8

My weather layouts. Had a lot of troubles until I realised to delete greyed out constraints that were unused and confusing the process.

I have one question, how do you make it so the three different items all stay exactly 1/3 of the height apart no matter what the size? I have read about using invisible view boxes to space items but thought there might be a better way.


#9

Code for launch sequence.

for var index = 5; index >= 0; --index {
println(“Time untill launch is (index)”)
sleep(1)
}


#10

Cant get the array one to work what is the answer?


#11

Which question are you stuck on?


#12

This looks terrific!

I’m going to be doing some new videos help with Auto Layout examples like this one.

I would probably modify the Regular x Regular layout to make the images bigger, that might be easiest. Did you make any progress?

Alternatively you could setup constraints using that spacer UIView, and you can change the priorities of the constraints (it may get a little complicated).

I’ll try and think through some options for you.


#13

Hey Paul,
Great course on swift! Check out Seasoned, a local weather app.


#14

Very nice @Maestro !

You will want to check for nil when you try and force unwrap – otherwise it crashes on the lines where you parse JSON.

    init(data: JSON) {
    let currently = data["currently"]
    
    let ct = currently["time"].int!    // <<< crash here from time not existing
    currentTime = dateStringFromUnixTime(ct)
    
    let ic = currently["icon"].string!
    icon = weatherIconFromString(ic)
    
    let tp = currently["temperature"].int!
    temperature = temperatureInCelsius(tp)
    
    humidity = currently["humidity"].double
    precipProbability = currently["precipProbability"].double
    summary = currently["summary"].string
}

#15

Hi am having an issue with the count down app. I made a label that will count down from 5 to 0 when you push a button using a for loop, but for some reason my label wont refresh throughout the for loop. So when you push the button the label changes to 0 five seconds after the push (without going from 5-4-3-2-1). Anyone know what I can do?

@IBAction func pushButton(sender: AnyObject) {
for i in 0…5{

        label.text = "\(5-i)"
        label.backgroundColor = UIColor.purpleColor()
        label.sizeToFit()
        sleep(1)

}
}

#16

I’ve added button to change from celsius into fahrenheit and vice versa.

here’s my code.

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var DateLabel: UILabel!

@IBOutlet weak var townLabel: UILabel!
@IBOutlet weak var temperatureButton: UIButton!

@IBOutlet weak var rainLabel: UILabel!
@IBOutlet weak var humidityLabel: UILabel!


var myTown: String!
var temperature: Int16!
var celsius: Float32!
var farenheit: Float32!
var humadity: Int8!
var rainProbability: Int8!
var selectCelsius: Bool!

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 1 F = (1 C * 1.8) + 32
    myTown = "Nonthaburi"
    townLabel.text = myTown

    celsius = 33
    selectCelsius = true
    
    humadity = 56
    humidityLabel.text = String(humadity)+"%"
    rainProbability = 0
    rainLabel.text = String(rainProbability)+"%"
    
    currentTimeStamp()
}

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

@IBAction func changeTempButton(sender: UIButton) {
    
    if (selectCelsius == true) {
        
        selectCelsius = false
        farenheit = (celsius * 1.8) + 32
        sender.setTitle("\(farenheit)°f", forState: UIControlState.Normal)
    }
    
    else if (selectCelsius != true) {
        
        selectCelsius = true
        sender.setTitle("\(celsius)°c", forState: UIControlState.Normal)
    }
    
    println("button")
}

func currentTimeStamp() {
    
    var localDate = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle:  NSDateFormatterStyle.FullStyle, timeStyle: NSDateFormatterStyle.ShortStyle)
    
    DateLabel.text = "\(localDate)"
    
    println("\(localDate)")

 }

}

#17

@coreysm10

You would need to use an NSTimer to fix this issue. Using sleep(1) hangs the thread, which isn’t what you want. It works good for demo purposes, but you wouldn’t use it for your situation.

You’ve created a tight for loop that is going to hang the entire UI, so nothing else on the main thread can execute. It’ll lock up user input and any UI updates.

Using the NSTimer you can create an update method that will run every second, or check the time and automatically update the UI.


#18

Hello. I’m new to the forum. Here’s my solution for the 2nd part of the code exercise.

var photoNameArray = [“Apple.png”, “Mexico.png”, “Owl.png”]
var photoPath = "~/pictures"
var photosToUpload: [String] = []

for filename in photoNameArray {
photosToUpload.append(photoPath + “/” + filename)
}
photosToUpload.description