본문 바로가기

프로젝트

(78)
01. 프로젝트 구성, UI 구현 프로젝트 구성 Coredata는 위와 같이 수정한다. 완료 여부를 판단할 isCompleted, 할 일의 정보를 저장할 각각의 속성이다. // 수정 전 import CoreData struct PersistenceController { static let shared = PersistenceController() static var preview: PersistenceController = { let result = PersistenceController(inMemory: true) let viewContext = result.container.viewContext for _ in 0.. Content init(displayPendingTask: Bool, filterDate: Date, content:..
00. 시작하며 시작하며 최근 앱들을 여럿 스토어에 등록했는데 슬슬 사용자들이 직접 데이터를 생성하고, 이를 관리할 수 있는 기능들에 대한 아이디어가 많아지고 있다. WWDC 2023을 기준으로 SwiftUI는 새로운 데이터 관리 도구인 SwiftData를 지원하기 시작했고, 이는 기존의 CoreData를 SwiftUI의 스타일에 맞도록 사용하는 새로운 패러다임이고 익숙해져야만 한다. 이를 위해 당분간은 CoreData를 기반으로 한 프로젝트들을 위주로 공부를 진행하고, SwiftData를 배워보면서 부족했던 부분을 채우고, 한 발 더 나아가는 기회로 삼고자 한다. 앱 Swift Swift - Apple Developer Swift is a powerful and intuitive programming language ..
TintTrove [Privacy Policy] Privacy Policy MinKyu CHA built the TintTrove app as a Free app. This SERVICE is provided by MinKyu CHA at no cost and is intended for use as is. This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service. If you choose to use my Service, then you agree to the collection and use of information in..
JusTheme [Privacy Policy] Privacy Policy MinKyu, CHA built the JusTheme app as a Free app. This SERVICE is provided by MinKyu, CHA at no cost and is intended for use as is. This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service. If you choose to use my Service, then you agree to the collection and use of information i..
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(..