본문 바로가기

전체 글

(380)
📌 Swift에서 독서 계획 내에 독서 메모를 CRUD하는 방법 (CoreData + Combine + MVVM) 🔹 목표독서 계획(ReadItem) 안에 여러 개의 독서 메모(ReadMemo)를 추가하고 관리하는 기능을 CoreData의 관계(Relationship) 를 활용하여 저장하고, Combine + MVVM 패턴으로 CRUD 기능을 구현한다. 🔹 1. CoreData에 ReadItem ↔ ReadMemo 관계 설정✅ ReadItem (독서 계획)id: UUIDtitle: StringstartDate: DateendDate: Datememos: ReadMemo와 1:N 관계 (📌 중요!)✅ ReadMemo (독서 메모)id: UUIDparentID: UUID (ReadItem과 연결)memo: Stringpage: IntreadItem: ReadItem과 관계 설정 (📌 중요!)💡 CoreData ..
📅 독서 시간을 완료한 날짜 저장하여 표시하기 ✅ 독서 기간: 3월 23일 ~ 3월 26일 경우 "⚪️ ⚪️ ⚪️ ⚪️" 총 4개로 저장 ✅ "🟢" 당일 독서 시간을 완료할 경우 ✅ "🔴" 당일 독서 시간을 완료 못할 경우  ✅ 1. ReadItemModel 검토extension ReadItemModel { var completedDates: [String: Bool] { let key = "completed_dates_\(self.id.uuidString)" return UserDefaults.standard.dictionary(forKey: key) as? [String: Bool] ?? [:] }} 👍 좋은 점UserDefaults 키를 UUID로 고유하게 설정해서 중복 방지 잘 했고모델 내에서 저장된 ..
🎉 타이머가 완료된 시점에 사용자에게 알림을 주기! ✅ 1. 화면이 열려 있을 때 (포그라운드 상태)화면이 켜져 있고 타이머가 끝났을 때 알림창(Alert)이나 경고음(Sound)을 주려면, stopTimer() 호출 직후에 추가@objc func refreshValue() { guard let startDate = userDefaults.object(forKey: startDateKey) as? Date else { return } let elapsed = Int(Date().timeIntervalSince(startDate)) let updatedRemaining = baseRemainingSeconds - elapsed if updatedRemaining > 0 { remainingSeconds = updat..
🔥 시작일 ➡️ 종료일 포함하여 날짜 계산! ✅ 두 날짜 간의 차이를 일(day) 단위로 계산해주는 메서드private func daysBetween(_ start: Date, _ end: Date) -> Int { let calendar = Calendar.current let components = calendar.dateComponents([.day], from: start, to: end) return (components.day ?? 0) + 2}  ✅ 메서드 사용하기func configure(_ readItem: ReadItemModel) { titleLabel.text = readItem.title let startDate = readItem.startDate let endDate = readItem.e..
❓backgroundColor와 contentView.backgroundColor의 차이 1. backgroundColorUITableViewCell 자체의 배경색을 설정.셀의 바깥쪽 전체 배경색을 담당.contentView가 차지하지 않는 영역(즉, 셀과 셀 사이의 간격이나 inset으로 인해 생긴 공간)에 영향을 줌. 2. contentView.backgroundColor셀의 **내용이 들어가는 부분(contentView)**의 배경색을 설정.UITableViewCell은 contentView라는 서브뷰를 기본적으로 가지고 있으며, 모든 UI 요소는 여기에 추가되는 게 일반적.contentView.layer.cornerRadius = 10 같은 설정이 이 영역에만 적용됨.override init(style: UITableViewCell.CellStyle, reuseIdentifier: S..
❌ 날짜 잘못 선택하면.. 오류창 띄워야 하는데.. Attempt to present on (from ) which is already presenting .✅ 무슨 뜻인가?UIAlertController를 띄우려고 했는데, 이미 UIDatePicker가 화면에 떠 있는 상태즉, UIDatePicker(날짜 선택기)가 presented 상태라서, UIAlertController를 추가로 띄울 수 없음UIAlertController는 한 번에 하나만 띄울 수 있음 ✅ 해결 방법: UIDatePicker 닫힌 후에 UIAlertController 띄우기🔨 dismiss(animated:completion:)로 UIDatePicker 닫은 후 UIAlertController 띄우기👉 먼저 UIDatePicker를 닫고, 완료 후 UIAlertContro..
🤔 실시간.. 버튼 활성화 해보기 (Combine) 📝 구현하려는 로직독서 계획을 세울 때,  책 제목은 2글자 이상, 독서 시간은 5분 이상이어야지만 일정 생성 버튼이 활성화 (활성화 시 배경색이 green으로 변경) 근데 지금 문제는 다음과 같다. 아래의 유효성 검사를 당하는 주체가 newCreatedItem 인데, 지금 이 주체는 저장을 해야하지만 활성화된다. 따라서 이런 유효성 검사를 하면 계속 비활성화가 된다.  따라서 AddPlanViewController에 있는 readItem을 ViewModel.newCreatedItem에 연결해야한다.   📌 MVVM + Combine 패턴에서 saveButton이 비활성화되는 문제 해결✅ readItem과 newCreatedItem을 실시간으로 동기화해야 유효성 검사가 정상적으로 동작함.✅ readI..
🤔 테이블 셀에 별도의 UITableViewCell을 만들지 않는다면? // ✅ 기본 UITableViewCell 등록 addItemTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")// MARK: - Extension: 테이블 델리게이트 설정extension AddPlanViewController: UITableViewDelegate, UITableViewDataSource { ... // ✅ 각 셀을 별도로 만들지 않음 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { switch AddItemTableSectio..