100 Days of SwiftUI - Day 26
Project 4: BetterRest
Project 4 - BetterRest를 시작한다.
이번 어플은 -
- 사용자의 예상 기상 시간을 계산하는 어플
- 사용자에게 3가지를 입력받는다: 기상 시간, 자는 시간, 사용자가 하루에 마시는 커피의 잔 수
- 애플의 머신러닝 라이브러리인
CoreML
을 사용 - 3개의 입력값을 사용하여 머신러닝 모델을 훈련
DatePicker
를 사용하여 날짜를 입력Stepper
를 사용하여 숫자를 입력
https://github.com/twostraws/HackingWithSwift 에서 훈련 데이터를 받을 수 있다.
본격적으로 프로젝트를 시작하기 전에, 이번 챕터에서 사용할 뷰에 대해 먼저 알아본다.
Stepper
+버튼과 -버튼을 사용하여 숫자를 입력할 수 있다.
비슷한 뷰로는 Slider
가 있지만 Stepper
보다는 정확도가 떨어진다.
Stepper
는 원하는 숫자 타입에 모두 바인딩된다.
Stepper("\(sleepAmount) hours", value: $sleepAmount)
값의 범위는 기본적으로 데이터 타입의 크기이다. 제한을 지정하지 않은 경우 데이터 타입의 범위만큼 값이 늘어날 수 있고, 줄어들 수 있다.
값의 범위를 제한하기 위해 in
매개변수를 사용한다.
Stepper("\(sleeAmount) hours", value: $sleepAmount, in:4...12)
값이 최소 4, 최대 12의 범위에서 늘어나고 줄어든다.
값의 변화는 1씩 일어나지만, 원한다면 변화의 양을 조절할 수 있다. step
매개변수에 변화량을 설정한다.
+나 -버튼을 누를 때마다 변하는 값을 조절할 수 있다.
step
매개변수에 사용하는 타입은 value
매개변수에 사용한 프로퍼티의 타입을 따라야 한다.
만약 Int
타입 값을 가지는 프로퍼티를 바인딩했다면 step
매개변수에는 Double
타입 숫자를 사용할 수 없다.
Stepper("\(sleepAmount.formatted()) hours", value: $sleepAmount, in:4...12, step:0.25)
// 출력되는 값을 깔끔하게 보여주기 위해 `formatted()`를 사용하여 정리한다.
이전에는 값이 1씩 증가하거나 감소했지만, step
에 0.25를 지정하면 값이 0.25씩 증가하거나 감소한다.
값이 증가, 감소할 때 다른 작업을 하기 원한다면, onIncrement
와 onDecrement
클로저에 원하는 작업을 입력한다.
Stepper() {
} onIncrement: {
//값이 증가할 때 실행될 코드
} onDecrement: {
//값이 감소할 때 실행될 코드
}
DatePicker
날짜를 선택할 수 있게 하는 뷰이다.
Date
라는 날짜를 다루는 타입이 있다.
@State private var wakeUp = Date.now
...
DatePicker("Date", selection: $wakeUp)
레이블을 숨기고 싶다면 .labelsHidden()
수정자를 사용한다.
레이블은 화면에 보이지는 않지만, VoiceReader같은 스크린 리더는 여전히 읽을 수 있다.
displayedComponent
매개변수를 통해 DatePicker가 어떤 요소를 보여줘야 할지 설정할 수 있다.
- 옵션을 지정하지 않는 경우 : 연/월/일/시/분 을 표시한다.
.date
: 연/월/일 을 표시한다..hourAndMinute
: 시/분 을 표시한다.
Stepper
에 있던 in
옵션이 DatePicker
에도 있다. 비슷하게 날짜의 범위를 지정하면 그 범위를 벗어나게 지정하지 못한다.
Date
연/월/일/시/분/초/표준 시간대를 캡슐화하는 타입.
Date.now
: 코드가 액세스한 현재의 시간과 날짜 정보를 담은Date
타입을 리턴한다.
Calendar
날짜에 대한 계산 기능을 제공
DateComponents
Date
에서 연/월/일/시/분/초 의 계산을 일관적으로 할 수 있도록 캡슐화함
var components = DateComponents()
components.hour = 8
components.minute = 0
let date = Calendar.current.date(from: components)
.date
는 옵셔널을 반환할 수 있기 때문에 nil 병합을 사용한다.
//날짜를 계산하여 반환하는데 실패하면 현재 날짜를 가져오도록함.
let date = Calendar.current.date(from: components) ?? .now
let components = Calendar.current.dateComponents([.hour, .minute], from: someDate)
let hour = components.hour ?? 0
let minute = components.minute ?? 0
날짜 포맷 설정
날짜와 시간을 포매팅하는 두가지 방법이 있다.
format
매개변수를 사용하는 방법 ~~~swift //시, 분을 출력 Text(Date.now, format: .dateTime.hour().minute())
//연, 월, 일을 출력 Text(Date.now, format: .dateTime.day().year().month())
포맷은 iOS의 사용자 로케일 설정에 따라 정렬된다. 수정자의 순서에 관계없다.
2. `formatted()` 메소드를 사용하는 방법
`Date`의 `formatted()` 메소드를 사용하여 날짜에 대한 구성 옵션을 지정할 수 있다.
~~~swift
Text(Date.now.formatted(date: .long, time: .shortened))
CoreML, CreateML
CoreML
,CreateML
머신러닝 프레임워크이다. CoreML
으로 머신러닝 어플을 만들 수 있고, CreateML
으로 머신러닝 모델을 생성할 수 있다.
Xcode에서 다음 경로를 통해 CreateML 툴로 진입할 수 있다.
Xcode > Open Developer Tools > Create ML