[swift] UIDatePicker 을 이용한 시작시간 종료시간
1. UIDatePicker
- 시간 및 날짜를 선택할 수 있게해주는 UI클래스인데 클래스 자체에 델리게이트 메서드가 없어져 valuechange라는 이벤트 상태에 메서드를 붙여줘야 활용이가능하다. 뭐 실시간 반응이 필요 없으면 그냥 datepicker 의 date만 받아와서 사용해도 무방하다.
2. UIDatePicker를 이용한 시작 종료 날짜 구현
@IBOutlet weak var dolbomStartTimeView: UIView!
@IBOutlet weak var dolbomStartTimeLabel: UILabel!
@IBOutlet weak var dolbomStartDateLabel: UILabel!
@IBOutlet weak var dolbomEndTimeView: UIView!
@IBOutlet weak var dolbomEndDateLabel: UILabel!
@IBOutlet weak var dolbomEndTimeLabel: UILabel!
@IBOutlet weak var datePickerView: UIDatePicker!
var dolbomStartTimeViewIsSelected : Bool = true;
일단 아웃렛먼저 잡아준다. dolbomStartTimeView 는 시작시간에 해당하는 뷰 dolbomStartTimeLabel은 시간 DateLabel은 날짜를 표시해주는 라벨인데 뭐 라벨하나로도 linebreak wordwrap 속성 걸어주고 해도되겠지만 그냥 두개나누는게 글자크기따로바꾸기편해서 두개로 뒀다.
아그리고 시작시간과 종료시간중 어떤것이 선택되어있는 상태인지를 판별하는 bool변수 하나 선언해준다. 맨처음 view가 load되었을때 시작시간이 선택된 상태이므로 값은 true로 준다.
self.datePickerView.minuteInterval = 10;
datePickerView.addTarget(self, action: #selector(dolbomDatePickerIsChanged(picker:)), for: .valueChanged);
minuteInterval은 분선택 picker에서 표시되는 분단위를 설정하는건데 1분단위로 나오게하고싶다면 그냥 따로 설정을하지않으면된다.
그다음 datepicker 값이 변경될때 실행되는 메서드를 추가해준다. 내가 사용한 메서드는 solbomDatePickerIschanged.
func dolbomDatePickerIsChanged(picker:UIDatePicker) {
if(dolbomStartTimeViewIsSelected){
let dateFormatter : DateFormatter = DateFormatter();
dateFormatter.dateStyle = .full;
let timeFormatter : DateFormatter = DateFormatter();
timeFormatter.timeStyle = .short;
dolbomStartDateLabel.text = dateFormatter.string(from: picker.date);
dolbomStartTimeLabel.text = timeFormatter.string(from: picker.date);
}else{
let dateFormatter : DateFormatter = DateFormatter();
dateFormatter.dateStyle = .full;
let timeFormatter : DateFormatter = DateFormatter();
timeFormatter.timeStyle = .short;
dolbomEndDateLabel.text = dateFormatter.string(from: picker.date);
dolbomEndTimeLabel.text = timeFormatter.string(from: picker.date);
}
}
DateFormatter 라는것은 date값을 입력받아서 지정된 포맷의 스트링으로 반환해준다던지 지정된 포맷의 스트링을 받아 date형으로 다시돌려주는 역할을 해준다. 이거하나면 날짜 정복가능하다.
뭐 별로의 형식으로 직접 스트링으로 지정해주지않아도 style 속성의 여러옵션을 이용해서 지정가능하다.
두개의 라벨을 쓸거기때문에 포메터를 두개 선언해서 하나는 날짜포맷 하나는 시간포맷으로 설정해서 스트링으로반환되는 값을 라벨에다가 붙여줬다.
한라벨에 쓰고싶으면 그냥 formatter 하나에 datestyle, timestyle 두개다 추가해주면된다.
func timeEndViewSelected(gesture : UITapGestureRecognizer){
dolbomStartTimeView.backgroundColor = UIColor.white;
dolbomEndTimeView.backgroundColor = UIColor.blue;
if let _ = dolbomEndTimeLabel.text?.isEmpty {
let dateFormatter = DateFormatter();
dateFormatter.dateFormat = "yyyy년 M월 dd일 eee a h:mm"
dateFormatter.amSymbol = "오전";
dateFormatter.pmSymbol = "오후";
let dateString = "\((dolbomEndDateLabel.text)!) \((dolbomEndTimeLabel.text)!)";
let date = dateFormatter.date(from: dateString);
datePickerView.date = date!;
}else{
}
dolbomStartTimeViewIsSelected = false;
dolbomStartTimeView.isUserInteractionEnabled = true;
dolbomEndTimeView.isUserInteractionEnabled = false;
}
이제 뷰가 선택되었을때 데이트피커가 자동으로 선택된뷰의 날짜와 시간으로 변경되게하는 부분인데
위의 데이트 받아오는부분을 반대로해주면 된다. 데이트 포맷을 string으로 받아와준다음 다시 date값으로바꿔주고 이것을 date picker의 date property에 집어넣어주면 자동으로 피커의 값이 바뀌게된다.
eee a h:mm 에서 a는 am,pm을 나타낸다.
그냥 혹시나있을 사용자버그 처리할려고 선택이되어있는뷰는 interaction을 불가능하게만들어준다.
func setFirstPickerDateTimeLable(){
var nowDateTime = Date();
let tmpDateFormatter = DateFormatter();
tmpDateFormatter.dateFormat = "yyyy.M.dd.e.HH.mm";
let dateString : NSString = tmpDateFormatter.string(from: nowDateTime) as NSString;
var dateArray : NSMutableArray = NSMutableArray.init();
dateArray = dateString.components(separatedBy: ".") as! NSMutableArray;
let tmpMin = Int(dateArray.object(at: 5) as! String)! % 10;
nowDateTime.addTimeInterval(TimeInterval((10-tmpMin)*60));
let dateFormatter = DateFormatter();
dateFormatter.dateFormat = "yyyy년 M월 dd일 eee요일";
let timeFormatter = DateFormatter();
timeFormatter.dateFormat = "a h:mm";
timeFormatter.amSymbol = "오전";
timeFormatter.pmSymbol = "오후";
dolbomStartDateLabel.text = dateFormatter.string(from: nowDateTime);
dolbomEndDateLabel.text = dateFormatter.string(from: nowDateTime);
dolbomEndTimeLabel.text = timeFormatter.string(from: nowDateTime);
dolbomStartTimeLabel.text = timeFormatter.string(from: nowDateTime);
let pickerDateFormatter = DateFormatter();
pickerDateFormatter.dateFormat = "yyyy년 M월 dd일 eee a h:mm"
pickerDateFormatter.amSymbol = "오전";
pickerDateFormatter.pmSymbol = "오후";
let pickerDateString = "\((dolbomStartDateLabel.text)!) \((dolbomStartTimeLabel.text)!)";
let pickerDate = pickerDateFormatter.date(from: pickerDateString);
datePickerView.date = pickerDate!;
}
이제 뷰가 로드됬을때 라벨의 시간을 초기화시켜줘야하는데 date 객체를 생성하면 기본적으로 현재시간을 받아온다. 현재 시간과 날짜를 . 으로나눈뒤 배열에 각각 저장하였다. 나는 시간을 10분단위로 설정하기때문에 현재 분 의 일자리단위를 버리고 10분이추가된상태의 시간을얻고싶어서 따로처리를해주었다.
그냥 현재시간그대로얻고싶다면 중간과정생략해도상관없다.
일단 10분단위로 쪼개는 과정은 13분이면20분 25분이면 30분 이런식의 표현을원하기때문에 일자리단위를 구해줘야하는데 그냥 % 10 해주면된다.
그리고 date클래스에는 addTimeInterval이라는 아주 편리한 메서드가있다. 받아온시간에서 초단위로 몇초뒤의 시분날짜를 자동으로 계산해준다. 여기서 내가필요한것은 일의자리를뺀 이후의 10분값이기때문에 (10-일의자리) * 60값을 더해준다.(일의자리는 분단위고 addinterval하는것은 초단위이기때문)
혹시나하는마음에 timeinterval에 대한 설명을 해놨는데 if문으로 시간처리하는 바보같은짓은 하지않길바란다..
그뒤에 위에서와같이 picker또한 초기화시켜주면끝!
3.exception
개발언어 english로두면 아마 optional 오류가날텐데 date형식때문에그렇다. 뭐 localization해주면상관없는데어차피한국에서만쓸거니 pass
한국어설정하는방법은혹시나해서... 시뮬레이터 설정 -> 일반-> 언어및지역 -> 한국어선택해주시면된다.