iOS & Swift 공부 (5) - Egg Timer 만들기

김영채 (Kevin)·2021년 1월 8일
0

iOS & Swift

목록 보기
17/107

오늘은 위와 같은 달걀 타이머를 만드는 법을 살짝 배웠다. Soft, Medium, Hard 에 따라 달걀을 삶는 시간이 다르니, 각각을 눌렀을 때 다른 타이머가 동작한다. 그리고 타이머가 1초씩 진행되면서 아래의 Progress Bar 도 변할수 있도록 코딩해줘야 한다.


타이머가 종료되면 위와 같이 progress bar 도 노란색으로 채워져야하며, 가장 상위의 레이블도 DONE을 표시함과 동시에 완료 알람 소리도 나도록 구현하는 실습을 진행했다.

우선 대략적인 Interface 는 위와 같이 구성되어 있다. 상위에 Vertical Stack View 가 있으며 이 부분이 화면에 나와있는 3개의 큼직큼직한 요소들을 담고 있는 스택 뷰다. 이 스택 뷰에 Title View, Egg Stack View, 그리고 Timer View 가 포함되어 있다.

Egg Stack View 는 3가지 종류의 달걀 뷰를 포함하고 있다. 나중에 각 달걀을 눌러서 특정 함수를 실행시켜야 하기 때문에 일단 Button 으로 구현하였다.
Timer View 안에는 Progress Bar 가 들어가있다.

이렇게 3개의 별도의 View 를 배치하여 최종적으로 하나의 Vertical Stack View 로 묶어주는 이유는 Auto Layout 때문인 것 같다. 모든 요소들을 한 방에 묶어 쉽게 constraints 를 정의하면, 기기의 해상도가 어떻든 관리가 쉬워지기 때문이다.

다음은 코드 부분이다.

우선 달걀 3개를 Dictionary 형태로 정의하였다. 달걀 삶는 시간이 3,5,7초만 걸리는 것은 아니고, 나중에 Timer를 작동시키면 빨리 테스트하기 위해 일단은 시간을 저렇게 짧게 설정하였다.

다음으로 달걀을 삶는 데 필요한 총 시간을 나타내는 변수 totalTime. 그리고 progress bar 의 진행을 도와줄 secondsPassed 변수까지 선언하였다.
player 변수는 타이머가 완료되면 짧은 음악을 들려주기 위한 변수다. timer 는 짐작하겠지만 타이머 관리를 위한 변수다.

hardnessSelected ( ) 함수는 달걀 3개 중 하나를 터치하면 실행되도록 연결시켜주었다. 함수의 매개변수가 sender: UIButton 이렇게 되어있는데, 달걀 3개 중 어느 하나를 클릭하든, 그 달걀은 sender 라는 이름으로 함수로 들어오게 된다.

함수의 첫 실행은 대부분 초기화 과정이다.

timer.invalidate()
//타이머 초기화

progressBar.progress = 0.0
//아래 progress bar 를 0.0 으로 설정 (Float 타입이라 소수로 적어줘야 함)

totalTime = eggTimes[sender.currentTitle!]!
//어떤 달걀을 선택하느냐에 따라 총 삶는 시간이 다르기에 버튼을 눌렀을 때 적절히 
//받아올 수 있도록 해야 함.
//단, Attributes Inspector 에 미리 각 달걀에 대한 Title을 3,5,7로 
//정의를 한 상태여야 함

secondsPassed = 0
//몇 초가 지났는지 추적하기 위한 변수. Progress bar 를 위해 필요

topLabel.text = sender.currentTitle!
//어떤 달걀을 눌렀는지에 따라 상단에 Soft, Medium, Hard 가 뜨게함

timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true)
//아까 선언한 timer 변수를 이용해서 실제 타이머의 세부 내용 정의 
//1초 단위로 설정하였음
//1초가 지날 때 마다 updateCounter 함수가 실행될 수 있도록 함.
//updateCounter는 사용자 정의 함수

다음은 내가 따로 정의한 updateCounter ( ) 함수다. 1초가 지날 때마다 이 함수가 실행이 된다. 선택한 총 달걀 삶는 시간이 다 되기 전까지는 secondsPassed 변수는 +1 이 되며, 그럴 때마다 인터페이스 아래의 progress bar 가 업데이트 된다. 이를 위해서 progressPercentage 변수를 추가로 선언하였다.

progressPercentage 값은 secondsPassed / totalTime 로 구하면 되며, 이는 progress bar 의 progress 프로퍼티가 0.0~1.0 사이로 지정을 해줘야해서 이런 식을 만들었다.

예를 들어, Soft 계란을 누르고 1초가 지났으면 1.0/3.0 = 0.333이 된다. 이 값을 progress bar 의 progress 프로퍼티 (progressBar.progress) 에 대입 시키면 30%로 인식한다. 그러면 약 30% 진행이 된 모습을 확인할 수 있게 된다.

마지막으로 totalTime이 지나면, done()이라는 함수를 실행하게끔 정의해주었다.

done 함수에서는 마무리 작업을 한다.

timer.invalidate()
//타이머 작동 중지

topLabel.text = "DONE"
//상단 레이블을 DONE으로 표시하게끔 함

progressBar.progress = 1.0
//진행 바를 100%로 맞춘다

let url = Bundle.main.url(forResource: "alarm_sound", withExtension: "mp3")
//alarm_sound.mp3 라는 음원 파일이 실행될 수 있도록 미리 url 지정

player = try! AVAudioPlayer(contentsOf: url!)
player.play()
//AVAudioPlayer 객체 생성 및 재생 시작
profile
맛있는 iOS 프로그래밍

0개의 댓글