📱 App Development Study/iOS🍎

[Udemy iOS & Swift Bootcamp] Egg Timer 만들기 (feat. Timer, UIProgressView)

ibelieveinme 2023. 3. 25. 15:59
728x90

Udemy iOS & Swift Bootcamp 8강 Egg Timer 만들기이다.

 

soft, medium, hard 계란을 만드는데 걸리는 시간을 화면에 보여주고, 1초가 흐를 때마다 progress bar에 진행상황을 보여주는 것이 메인 기능이다. 실로폰 앱 만들기에서 배웠던 마지막 종료 효과음도!

 

if/else문 switch문, Dictionary, !? 키워드, @objc 키워드, Countdown Timer, UIProgressView 를 배웠다.

기억하고 싶은 부분은 Timer코드와 UIProgressView이다.


1. Timer 기능 만들기

//Timer 기능 핵심코드

var countdownTimer: Timer!

countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)

 

Timer타이머 기능을 만들 수 있게 해주는 클래스다.

Timer.scheduledTimer의 인자를 살펴보자.

 

1) timeInterval: 얼마만큼의 시간만큼 Timer를 반복할 건지. ex) 1.0이면 1초이고 0이나 음수값을 입력하면 0.0001이 default로 실행된다.

2) target: selector에게 보낼 객체. self면 내 자신을 보낸다.

3) selector: timerInterval 경과마다 target을 보낼 함수를 입력한다. 난 updateTime이라는 함수를 만들어서 경과시간 마다 해야할 일을 적어주었다. 

4) userInfo: 타이머의 사용자 정보라는데 그런거 없으니까 nil 이라고 null값 입력해주기

5) repeats: Timer를 timeInteval 마다 반복수행할지 여부를 적는것. true 면 반복실행, false면 반복실행 안함. 반복실행시, selector 함수에 조건을 추가해줘서 일정 조건이 되면 Timer를 종료하는 코드를 넣어줘야 한다. 

 

//Timer 전체코드

var countdownTimer: Timer!
var totalTime = 0
    
func startCountdown(timeValue: Int){
    countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
}

//object C 에서 사용했던 함수라서 @objc 주석이 붙는 것.
@objc func updateTime() {
    if totalTime >= 0 {
        totalTime -= 1
    }
    else {
        endTimer()
    }
}
    
func endTimer() {
    titleText.text = "Done!"
    playSound()

    countdownTimer?.invalidate()
    countdownTimer = nil
}

updateTime 을 그냥 func 키워드만 쓰면 에러가난다. scheduledTimer함수가 Object-C에서 넘어온 코드라서 함수 앞에 @objc 참조 키워드를 적어주어야 한다.

 

자세한 내용은 Apple Developer 공식문서 참고

 

Timer | Apple Developer Documentation

A timer that fires after a certain time interval has elapsed, sending a specified message to a target object.

developer.apple.com

 

 

2. ProgressBar 만들기

//ProgressBar 기능 핵심코드

@IBOutlet weak var progressBar: UIProgressView!

progressBar.progress = Float(passedSeconds) / Float(totalTime)

 

progress가 진행바라서 이 수치를바꿔주면 된다.

0~1 이 %개념으로 늘어나는 것이다. 0.1 ~ 0.5 ~ 0.9 ~ 1 == 10% ~ 50% ~ 90% ~ 100% 이렇게.

 

이 때, 정수/정수 = 정수를 반환하므로 정수값은 나누기 전에 미리 실수로 바꿔서 나눠줘야 한다.

아니면 0이 나와서 progress에 적용이 안된다.

 

//ProgressBar  전체코드

import UIKit
import AVFoundation


class ViewController: UIViewController {
    var SECONDS = 1
    var countdownTimer: Timer!
    let eggTime = [
        "Soft": 5, "Medium": 7, "Hard": 12
    ]
    var totalTime = 0
    var passedSeconds = 0

    @IBOutlet weak var titleText: UILabel!
    @IBOutlet weak var progressBar: UIProgressView!

    var player: AVAudioPlayer?


    @IBAction func onClickEgg(_ sender: UIButton) {
        if countdownTimer != nil { endTimer() }
        progressBar.progress = 0
        passedSeconds = 0

        let hardness = sender.currentTitle!
        titleText.text = "\(hardness) Start"

        startCountdown(timeValue: eggTime[hardness]!)
    }

    func startCountdown(timeValue: Int){
        totalTime = timeValue * SECONDS
        countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
    }
    
    //object C 에서 사용했던 함수라서 @objc 주석이 붙는 것.
    @objc func updateTime() {
        if passedSeconds < totalTime {
            print("\(passedSeconds) seconds")
            passedSeconds += 1
            progressBar.progress = Float(passedSeconds) / Float(totalTime)
        }
        else {
            endTimer()
        }
    }

    func endTimer() {
        titleText.text = "Done!"
        playSound()

        countdownTimer?.invalidate()
        countdownTimer = nil
    }

    func playSound() {
        guard let url = Bundle.main.url(forResource: "alarm_sound", withExtension: "mp3") else { return }

        do {
            let player = try AVAudioPlayer(contentsOf: url)
            player.play()
        } catch let error {
            print(error.localizedDescription)
        }
    }
}

 

 


Timer, Progress 기능을 포함한 EggTimer 완성 앱

 

[만든 앱의 Layout]

[전체코드]

import UIKit
import AVFoundation

class ViewController: UIViewController {
    
    var SECONDS = 1
    var countdownTimer: Timer!
    let eggTime = [
        "Soft": 5, "Medium": 7, "Hard": 12
    ]
    var totalTime = 0
    var passedSeconds = 0

    @IBOutlet weak var titleText: UILabel!
    @IBOutlet weak var progressBar: UIProgressView!
    
    var player: AVAudioPlayer?

    
    @IBAction func onClickEgg(_ sender: UIButton) {
        if countdownTimer != nil { endTimer() }
        progressBar.progress = 0
        passedSeconds = 0
        
        let hardness = sender.currentTitle!
        titleText.text = "\(hardness) Start"
        
        startCountdown(timeValue: eggTime[hardness]!)
    }
    
    func startCountdown(timeValue: Int){
        totalTime = timeValue * SECONDS
        countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
    }
    
    //object C 에서 사용했던 함수라서 @objc 주석이 붙는 것.
    @objc func updateTime() {
        if passedSeconds < totalTime {
            print("\(passedSeconds) seconds")
            passedSeconds += 1
            progressBar.progress = Float(passedSeconds) / Float(totalTime)
        }
        else {
            endTimer()
        }
    }
    
    func endTimer() {
        titleText.text = "Done!"
        playSound()
        
        countdownTimer?.invalidate()
        countdownTimer = nil
    }
    

    func playSound() {
        guard let url = Bundle.main.url(forResource: "alarm_sound", withExtension: "mp3") else { return }

        do {
            let player = try AVAudioPlayer(contentsOf: url)
            player.play()

        } catch let error {
            print(error.localizedDescription)
        }
    }
}
728x90