본문 바로가기

프로젝트/FastingTimer

(7)
06. 더 나아가기 더 나아가기 | 난이도 선택하기, 개선하기 강의는 끝났지만 난이도를 선택하는 부분은 빠져있다. enum FastingPlan: String { case beginner = "12:12" case intermediate = "16:8" case advanced = "20:4" var fastingPeriod: Double { switch self { case .beginner: return 12 case .intermediate: return 16 case .advanced: return 20 } } } beginner와 intermediate, advance를 화면에서 직접 선택할 수 있도록 추가로 구현한다. 난이도 선택하기 | 인터페이스 구성하기 현재 앱의 화면은 위와 같고, 난이도를 선택하기 위해 다..
05. 기능 구현 #3 기능 구현 #3 | Upcoming time, Percentage, 실제 시간 반영하기 Upcoming time 타이머의 상태가 notStarted이면 elapsedTime과 remainingTime을 표시하는 것은 부자연스럽다. 선택된 난이도에 따라서 현재시간을 기준으로 다음 식사 시간을 나타내도록 수정한다. // MARK: Timer VStack(spacing: 30) { // MARK: Upcoming Time if fastingManager.fastingState == .notStarted { VStack(spacing: 5) { Text("Upcoming fast") .opacity(0.7) Text("\(fastingManager.fastingPlan.fastingPeriod, specifie..
04. 기능 구현 #2 기능 구현 #2 | Timer 구현 Timer 구현 | fastingTime, feedingTime 계산하기 class FastingManager: ObservableObject { @Published private(set) var fastingState: FastingState = .notStarted @Published private(set) var fastingPlan: FastingPlan = .intermediate @Published private(set) var startTime: Date @Published private(set) var endTime: Date var fastingTime: Double { return fastingPlan.fastingPeriod } var feeding..
03. 기능 구현 #1 기능 구현 #1 | FastingManager FastingManager | FastingState FastingManager는 본격적인 식단 관리 기능의 구현에 해당한다. FastingManager라는 이름의 파일을 새로 생성해 구현한다. import Foundation class FastingManager: ObservableObject { } ObservableObject 프로토콜을 채용한 클래스의 형태로, 해당 해당 클래스에 접근하는 View가 Published로 지정된 속성을 사용할 수 있게 된다. import Foundation enum FastingState { case notStarted case fasting case feeding } class FastingManager: Observa..
02. 인터페이스 디자인 #2 인터페이스 디자인 #2 ContentView ContentView | Header body의 가독성을 높이기 위해 구성되는 View들은 extension으로 구현한다. header는 현재 상태를 문장으로 표시하기 위한 TextView와 이후 Fasting Plan을 변경하는 버튼을 포함한다. struct ContentView: View { var body: some View { VStack { header ProgressRing() } } } extension ContentView { // MARK: Title, Fasting Plan var header: some View { VStack { Text("Let's get started!") .font(.headline) .foregroundColor(C..
01. 인터페이스 디자인 #1 인터페이스 디자인 #1 ProgressRing, Timer ProgressRing ProgressRing은 총 진행상황을 표시할 PlaceHolder와 현재 진행 상황을 표시할 진행링 두 개의 View의 조합이다. 같은 좌표에 겹쳐 표시돼야 하므로 ZStack으로 구현한다. struct ProgressRing: View { @State var progress = 0.0 var body: some View { 우선 진행 상태를 나타낼 변수를 하나 정의한다. var body: some View { ZStack { // MARK: Placholder Ring Circle() .stroke(lineWidth: 20) .foregroundColor(Color(UIColor.systemGray)) .opacity(..
00. 시작하며 이제 막 UIKit에 대한 공부를 마치고 작은 프로젝트를 진행하던 작년에 이야기다. 작은 프로젝트를 몇 개 해 봤지만 여전히 개념들은 어려웠고, 특히나 만들려고 했던 인터벌 타이머는 thread 분리와 함께 완전히 박살났다. 1초 간격으로 실행 돼야 할 코드가 어느 때는 0.5초 만에, 어느 때는 1초가 넘어서 동작하니 제대로 된 기능을 한다고 볼 수 없다. 올해는 SwiftUI를 배웠고, 다시 이전의 프로젝트를 재시동 하기 전에 시계나 타이머에 관한 프로젝트를 몇 개 해 보고자 한다. 이번에 만들어 보는 FastingTimer는 식단 관리 앱이다. 원형의 Indicator를 가지고 진행 상황을 알려주고, 매 초 업데이트 되니 내가 구현하려던 매커니즘과 동일하다고 할 수 있다. 앱 Swift Swift ..