관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 1. Timer 구현하기 - UIDatePicker 개념, Timer()로 구현 방법 본문

iOS 응용 (swift)

[iOS - swift] 1. Timer 구현하기 - UIDatePicker 개념, Timer()로 구현 방법

jake-kim 2021. 11. 23. 23:21

1. Timer 구현하기 - UIDatePicker 개념, Timer로 구현 방법

2. Timer 구현하기 - DispatchSourceTimer로 구현 방법 (Background에서도 동작)

3. Timer 구현하기 - CircularProgressBar UI 구현(CAShapeLayer 사용), DispatchSourceTimer와 Timer로 구현 방법

DatePicker를 이용하여 Timer를 구현한 모습


UIDatePicker 4가지 모드

  • UIDatePicker 인스턴스의 필드값 "datePickerMode" 사용

  • 4가지 종류

time

date

dateAndTime

countDownTimer

UIDatePicker 입력 값 얻는 방법

> .valueChanged 이벤트를 받아서, dataPicker.date로 값 접근

  • datePickerMode = .time인 경우 처리 방법
  • picker.date로 접근
lazy var timeDatePicker: UIDatePicker = {
    let picker = UIDatePicker()
    picker.datePickerMode = .time
    return picker
}()

@objc func didChangeTimeDatePicker(_ picker: UIDatePicker) {
    print(picker.date)
}

  • datePickerMode = .countDownTimer인 경우 처리 방법
    • picker.countDownDuration으로 접근
lazy var countDownDatePicker: UIDatePicker = {
    let picker = UIDatePicker()
    picker.datePickerMode = .countDownTimer
    picker.addTarget(self, action: #selector(didChangeCountDownDatePicker(_:)), for: .valueChanged)
    return picker
}()

@objc func didChangeCountDownDatePicker(_ picker: UIDatePicker) {
    print(picker.countDownDuration)
}

Timer 구현

  • 구현 아이디어
    • Timer의 scheduler에서 현재 시간과, 위의 기록된 시간을 비교하여 시간이 얼마나 지났는지 체크
    • 위와 같이 하면, 사용자가 background에 갔다와도 시간이 흐른만큼 Timer에 반영
  • Timer객체를 전역에 선언
    • Timer가 필요없을 때 invalidate시켜주기 위함
    • Timer를 새로 생성할 때 기존의 timer를 invalidate시켜주기 위함
private var timer = Timer()

deinit {
    timer.invalidate()
}

private func setTimer(with countDownSeconds: Double) {
    timer.invalidate() // <- 기존 타이머 삭제
    ...
  • 버튼이 눌린 경우, timer 시작
lazy var confirmTimerSettingButton: UIButton = {
    let button = UIButton()
    button.setTitle("확인", for: .normal)
    button.setTitleColor(.systemBlue, for: .normal)
    button.setTitleColor(.blue, for: .highlighted)
    button.addTarget(self, action: #selector(didTapConfirmButton), for: .touchUpInside)
    return button
}()
  • timer 구현
    • Unix time stamp값을 이용하여 현재시간과, UIDatePicker에서 설정한 시간의 차이를 이용하여 경과된 시간 계산
private func setTimer(with countDownSeconds: Double) {
	let startTime = Date()
    timer.invalidate()
    
    timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { [weak self] timer in
        let elapsedTimeSeconds = Int(Date().timeIntervalSince(startTime))
        let remainSeconds = Int(countDownSeconds) - elapsedTimeSeconds
        guard remainSeconds >= 0 else {
            timer.invalidate()
            return
        }
        
        self?.countDownLabel.text = "남은시간 = \(remainSeconds)초"
    })
    
}

cf) background 에서도 Timer가 동작하도록 설계 방법(추천): https://ios-development.tistory.com/775

 

* 전체 소스 코드: https://github.com/JK0369/ExDatePicker

 

* 참고

- https://developer.apple.com/documentation/uikit/uidatepicker

 

 

Comments