반응형
Notice
Recent Posts
Recent Comments
Link
Today
Total
07-05 05:44
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Archives
관리 메뉴

iOS 개발 기록 블로그

iOS(Swift) Timer Code (타이머 코드 개요, 이슈, 해결, 추가) 본문

iOS

iOS(Swift) Timer Code (타이머 코드 개요, 이슈, 해결, 추가)

crazydeer 2022. 5. 18. 12:13
반응형

타이머 예시 프로젝트 실행 화면

Swift에서 타이머를 생성하는 방법이다.

우선 다들 이러한 기능이 필요하면 하는 거 있잖아요.

구글링 합니다.

 

타이머 구글링

 

바로 위에 들어가면 코드가 딱 나온다.

그거 들어가서 아래로 내리면서 가장 투표 수 많은 것 + 내가 필요한 것인지 파악 후

갖다 쓰면 끝.

 

우선 저 프로젝트는 안젤라 유 선생님의 강의에서 나오는 예시 프로젝트이며

코드는 아래와 같다.

 

코드

importUIKit
 
class ViewController: UIViewController {
    
    let eggTime= ["Soft": 5, "Medium": 7, "Hard": 12]
    var counter: Int= 0
    
    @IBActionfunc hardnessSelected(_sender: UIButton) {
        
        let hardness = sender.currentTitle!
        counter= eggTime[hardness]!
        
        print("\(hardness)'s time: \(eggTime[hardness]!)")
        
        Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
    }
    
    @objc func updateCounter() {
        ifcounter> 0{
            print("\(counter) seconds...")
            counter-= 1
        }
    }
}

 

중간중간 띄어쓰기 이상한 건 나도 왜 그런지 모르겠다.

복붙 했을 뿐인데..

 

개요

프로젝트 개요는 3가지 단계의 달걀 삶는 시간 타이머이다.

 

임의로 각각 5초, 7초, 12초로 했다.

hardnessSelected 라는 버튼 클릭 시 클릭한 버튼의 이름(ex. "Soft")을 가져와 hardness 변수에 담는다.

eggTime 이라는 딕셔너리에서 해당하는 삶기 정도의 시간을 가져와 counter 변수에 담는다.

 

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

이 코드가 타이머 생성하는 건데 1.0초 간격으로 selector를 실행하는 것이다.

아래의 updateCounter 함수에서 정해진 시간을 감소시켜준다.

이게 다다.

 

문제

그런데 여기서 문제가 있다.

버튼을 여러번 눌렀을때 이미 생성되어 있던(1초 씩 감소되고 있는) 타이머가 삭제되지 않아서 두개가 감소한다.

1초에 1감소되는 타이머가 두개인 것이다.

그래서 대략적으로 1초에 2 감소하게 되는 문제가 있다.

 

이를 해결하기 위해서는 기존의 타이머를 삭제해줘야 한다.

 

 

해결 코드

import UIKit
 
class ViewController: UIViewController {
    
    let eggTime= ["Soft": 5, "Medium": 7, "Hard": 12]
    var counter: Int= 0
    var timer= Timer()
    
    @IBActionfunc hardnessSelected(_sender: UIButton) {
        
        timer.invalidate()  // when you clicked button, stop timer and cancel it
        
        let hardness = sender.currentTitle!
        counter= eggTime[hardness]!
        
        print("\(hardness)'s time: \(eggTime[hardness]!)")
        
        timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
    }
    
    @objc func updateCounter() {
        if counter> 0{
            print("\(counter) seconds...")
            counter-= 1
        }
    }
    
 
}

코드를 보면 세번째 줄에 timer라는 변수에 Timer()  타이머를 생성해주고

버튼을 클릭하자마자 timer변수를 invalidate() 해줘서 타이머를 멈추고 삭제해준다.

그러고 나서아래 Timer.scheduledTimer() 함수를 timer 변수로 생성해줬다.

이렇게 하면정상적으로 동작한다.

 

 

추가

추가적으로 타이머가 끝났을때도 삭제해주고 더불어 UI 상으로 Done! 이라고 알려보자.

 

코드 상단 부에 UI Label 연결

코드 상단에 IBOutlet으로 해당하는 UI Label 연결해준다.

 

 

타이머 시간 감소가 끝난 경우의 수 추가

그리고 코드 하단에 counter 0보다 크지 않을 경우 (else)

곧바로 위와 같이 timer.invalidate() 해주어 타이머를 제거해준다.

그다음 Done!으로 바꿔 주면 . 너무 쉽다.

 

콘솔창에 타이머 종료 후 UI 상 표기

 

시연 동영상

EggTimer Recording.mov
4.40MB

 

 

 

참고

안젤라 유 강의: https://www.udemy.com/share/101Wsa3@pF587yaXxA-kMi-oR5sprx4krwiVL1zkCVOrRi2s_QGCWv415buRPnFT-uAcM7eUgg==/

스택오버플로우: https://stackoverflow.com/questions/29374553/how-can-i-make-a-countdown-with-nstimer

 

How can I make a countdown with NSTimer?

How can I make a countdown with an NSTimer using Swift?

stackoverflow.com

 

반응형