Swift 4주차 - 데이트 피커 사용하기 (알람 시계 만들기)

2024. 3. 30. 23:01swift

Swift 4주차 - 데이트 피커 사용하기 (알람 시계 만들기)

 

이번 주차에서는 데이트 피커를 사용해 날짜를 선택하는 앱을 만들어보고, 해당 내용을 토대로 알람 시계 앱도 만들어 볼 예정이다.

 

 

목차

     

    데이트 피커(Date Picker)란?

     

    데이트 피커(Date Picker)는 날짜와 시간을 선택할 수 있게 해주는 객체이다.

     

    앱에서 날짜와 시간을 선택해야 할 때는 드롭 다운 방식이나 리스트 방식으로 보여줄 수 있는데 날짜는 선택 항목이 많기 때문에 데이트 피커 방식이 가장 효율적이라고 할 수 있다.

     

     

    데이트 피커 앱 화면 꾸미기

     

     

    우측 상단의 + 버튼을 눌러 데이트 피커 객체를 검색하고 스토리 보드에 끌어와 화면 중앙에 배치해 보자.

    Date Picker를 검색해서 찾을 수 있다.

     

     

     

    데이트 피커의 크기를 알맞게 키우고 오른쪽의 'Alttributes inspector' 버튼을 클릭한 후 Style을 'Inline'으로 변경하자.

     

    마찬가지로 Mode를 'Date and Time', Locale를 한국으로 바꿔주자.

     

     

    그리고 화면 상단과 하단에 각각 현재시간 레이블과 선택시간 레이블을 추가하자.

     

     

    해당 레이블들에서는 각각 현재 시간과 데이트 피커를 사용해 선택한 시간을 표시할 것이다.

     

     

    아웃렛 변수와 액션 함수 추가하기

     

    이제 ViewController 창을 함께 열어서 아웃렛 변수와 액션 함수를 추가해보자.

     

     

    현재시간 레이블 이름은 'lblCurrentTime'으로 설정하자.

     

     

     

    선택시간 레이블 이름은 'lblPickerTime'으로 설정하자.

     

     

     

    마지막으로 데이트 피커는 이름을 'changeDatePicker'로 설정하고, 타입을 'UIDatePicker'로 바꿔주자.

     

    이제 아웃렛 변수와 액션 함수 추가가 모두 완료되었다.

     

     

    선택한 날짜 및 시간 출력하기

     

    이제 데이트 피커를 사용해서 선택한 날짜 및 시간이 출력되도록 코드를 작성해 보자.

     

     

    앞에서 만든 액션 함수인 changeDatePicker에 아래 코드를 추가하자.

     

    @IBAction func changeDatePicker(_ sender: UIDatePicker) {
        let datePickerView = sender // 1
        
        let formatter = DateFormatter() // 2
        formatter.dateFormat = "yyyy-MM-dd HH:mm EEE" // 3
        lblPickerTime.text = "선택시간: " + formatter.string(from: datePickerView.date) // 4
    }

     

      1. UIDatePicker에서 넘어온 값을 datePickerView 상수에 할당한다.
      2. DateFormatter 객체를 생성한다. 객체를 사용하여 날짜와 시간을 원하는 형식으로 변환할 있다.
      3. DateFormatter dateFormat 속성을 설정한다. 포맷은 "년-월-일 시:분:초 요일"로 설정한다.
      4. 데이트 피커에서 선택한 날짜를 위 포맷대로 string를 사용해 문자열로 변환한다. 그 후 선택시간 레이블의 text에 해당 값을 넣는다.

     

     

    여기까지 작성하고 에뮬레이터를 실행시켜보자.

     

    데이트 피커로 원하는 날짜와 시간을 선택하면 '선택시간' 부분에 선택한 날짜와 시간이 표시되는 것을 볼 수 있다.

     

     

     

    타이머 기능 추가하기

     

    우선 타이머를 구동하기 위해서 필요한 변수 및 상수를 추가해 보자.

     

    class ViewController: UIViewController { 밑에 추가하자.

     

    class ViewController: UIViewController {
        
        let timeSelector: Selector = #selector(ViewController.updateTime) // 1
        let interval = 1.0 // 2
        var count = 0 // 
        ...

     

    코드를 입력하면 위와 같은 에러가 뜨게 되는데 ViewController 클래스에 updateTime 함수가 없기 때문에 발생한 것이다.

     

    이후에 해당 함수를 추가할 예정이니 지금은 이 에러를 무시해도 괜찮다.

     

     

    1. Selector는 Objective-C에서 메서드를 식별하는 객체다. Objective-C에서는 메서드의 이름을 문자열이 아닌 Selector 객체로 참조한다.

     

    #selector(ViewController.updateTime) updateTime 메서드를 참조하는 Selector 생성하는 문법이다. ViewController 클래스의 updateTime 메서드를 참조하기 위해 ViewController 클래스의 이름을 접두어로 사용한다. updateTime 메서드가 Objective-C 메서드처럼 동작할 있도록 @objc 키워드로 표시되어야 한다.

     

    2. 타이머의 간격값이다. 1.0은 1초를 의미한다.

    3. 타이머가 설정한 간격대로 실행되는지 확인하기 위한 변수이다.

     

     

     

    이제 viewDidLoad 함수에서 타이머를 설정해보자.

     

    타이머를 설정하기 위해 scheduledTimer 함수를 사용한다.

     

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        Timer.scheduledTimer(timeInterval: interval, target: self, selector: timeSelector, userInfo: nil, repeats: true)
    }

     

    • Timer.scheduledTimer 메서드를 사용하여 반복적으로 호출될 타이머를 생성한다.
    • timeInterval 매개변수에는 타이머의 간격을 지정한다. 위에서 설정한 interval 값인 1.0이 사용된다.
    • target 매개변수에는 타이머가 호출될 객체를 지정한다. 여기서는 self, 즉 현재 ViewController 객체가 타이머를 호출하게 된다.
    • selector 매개변수에는 타이머가 호출될 메서드를 나타내는 Selector를 지정한다. 위에서 생성한 timeSelector가 사용된다.
    • userInfo 매개변수는 추가 정보를 전달할 때 사용된다. 이 예제에서는 사용하지 않으므로 nil로 설정한다.
    • repeats 매개변수는 타이머가 반복되는지 여부를 나타낸다. true 설정하면 타이머가 반복된다.

     

     

    이제 타이머가 동작할 때 실행할 함수를 추가해 보자.

     

    소스코드 마지막 부분에 updateTime 함수를 추가해보자.

     

    @objc func updateTime() {
        lblCurrentTime.text = String(count)
        count = count + 1
    }

     

     

    #selector()의 인자로 사용될 메서드를 선언할 때 Objective-C와의 호환성을 위하여 함수 앞에 만드시 @objc 키워드를 붙여야 한다.

     

     

    이제 실행 버튼을 클릭해서 결과를 확인해보자.

     

     

    현재시간 레이블 숫자가 0부터 시작해서 1초에 1씩 증가하는 모습을 볼 수 있다.

     

     

    현재 시간을 읽는 함수 추가하기

     

    타이머가 정상적으로 동작하는 것을 확인했으니 현재 시간을 읽어 현재시간 레이블에 출력해보자.

     

    @objc func updateTime() {
    //   lblCurrentTime.text = String(count)
    //   count = count + 1 // 1
        
        let date = NSDate() // 2
        
        let formatter = DateFormatter() // 3
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss EEE" // 4
        lblCurrentTime.text = "현재시간: " + formatter.string(from: date as Date) // 5
    }

     

    1. 기존 소스를 주석처리 한다.
    2. 현재 시간을 NSDate 함수를 사용해서 가져온다.
    3. DateFormatter 객체를 생성한다. 객체는 날짜를 원하는 형식의 문자열로 변환하는 사용된다.
    4. 앞에서 선언한 상수 formatter의 dateFormat 속성을 설정합니다.
    5. NSDate 객체를 DateFormatter를 사용하여 지정된 형식의 문자열로 변환하고, 이를 lblCurrentTime의 텍스트로 설정한다. "현재시간: " 문자열과 변환된 날짜  시간 문자열이 결합되어 lblCurrentTime 표시된다.

     

    이제 최종 결과를 확인해보자.

     

     

    앱을 실행시켜보면 현재시간에 현재시간이 출력되며 1초마다 시간이 변하는 것을 확인할 수 있다.

    또한, 데이트 피커를 사용해 날짜를 선택하면 선택시간에 선택한 시간이 출력된다.

     

     

    전체 소스코드

     

    import UIKit
    
    class ViewController: UIViewController {
        
        let timeSelector: Selector = #selector(ViewController.updateTime)
        let interval = 1.0
        var count = 0
        
        @IBOutlet var lblCurrentTime: UILabel!
        @IBOutlet var lblPickerTime: UILabel!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
            Timer.scheduledTimer(timeInterval: interval, target: self, selector: timeSelector, userInfo: nil, repeats: true)
        }
    
        @IBAction func changeDatePicker(_ sender: UIDatePicker) {
            let datePickerView = sender
            
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy-MM-dd HH:mm EEE"
            lblPickerTime.text = "선택시간: " + formatter.string(from: datePickerView.date)
        }
        
        @objc func updateTime() {
    //        lblCurrentTime.text = String(count)
    //        count = count + 1
            
            let date = NSDate()
            
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy-MM-dd HH:mm:ss EEE"
            lblCurrentTime.text = "현재시간: " + formatter.string(from: date as Date)
        }
        
    }

     

     

     

    알람 시계 만들기

     

    지금까지 만든 코드를 사용해서 간단한 알람 시계를 만들어 보자.

     

    조건:

    1. 현재 시간이 선택 시간과 같게 되면 1분동안 배경 화면이 빨간색으로 변하게 하자.
    2. 1분이 지나면 다시 원래대로 흰색 배경화면으로 변경시켜 보자.

     

    완성된 코드는 다음과 같다.

     

    import UIKit
    
    class ViewController: UIViewController {
        
        let timeSelector: Selector = #selector(ViewController.updateTime)
        let interval = 1.0
        var count = 0
        var alarmTime = ""
        
        @IBOutlet var lblCurrentTime: UILabel!
        @IBOutlet var lblPickerTime: UILabel!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
            Timer.scheduledTimer(timeInterval: interval, target: self, selector: timeSelector, userInfo: nil, repeats: true)
        }
    
        @IBAction func changeDatePicker(_ sender: UIDatePicker) {
            let datePickerView = sender
            
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy-MM-dd HH:mm EEE"
            lblPickerTime.text = "선택시간: " + formatter.string(from: datePickerView.date)
            
            formatter.dateFormat = "hh:mm aaa"
            alarmTime = formatter.string(from: datePickerView.date)
        }
        
        @objc func updateTime() {
    //        lblCurrentTime.text = String(count)
    //        count = count + 1
            
            let date = NSDate()
            
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy-MM-dd HH:mm:ss EEE"
            lblCurrentTime.text = "현재시간: " + formatter.string(from: date as Date)
            
            formatter.dateFormat = "hh:mm aaa"
            let currentTime = formatter.string(from: date as Date)
            if (alarmTime == currentTime) {
                view.backgroundColor = UIColor.red
    
            } else {
                view.backgroundColor = UIColor.white
            }
        }
        
    }

     

     

    알람 시간을 담는 alarmTime 변수를 추가했다.

     

    UIDatePicker에서 날짜가 변경될 때 호출되는 메서드인 changeDatePicker에서 사용자가 선택한 날짜를 formatter 사용하여 "hh:mm aaa" 형식의 문자열로 변환하여 alarmTime 변수에 저장한다.

     

    매 초마다 실행되는 updateTime 메서드 안에 현재 시간과 알람 시간이 일치하는지 확인하는 조건문을 추가하여 현재 시간과 알람 시간이 일치하면 배경화면을 빨간색으로 바꾼다.

     

    만약 현재 시간과 알람 시간이 다르다면 다시 하얀색으로 변경한다.

     

     

    현재 시간과 선택(알람) 시간이 같을 때

     

     

    현재 시간과 선택(알람) 시간이 다를 때