From 7475a963bd921779310e6c9c9bd3b4b1b80370df Mon Sep 17 00:00:00 2001 From: songyc macbook Date: Mon, 3 Aug 2026 11:40:36 +0900 Subject: [PATCH] =?UTF-8?q?fix(diary):=20=EC=96=91=EC=8B=9D=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=ED=8E=9C=20=EC=83=89=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EA=B3=A0=EC=A0=95=20=E2=80=94=20=EB=8B=A4=ED=81=AC?= =?UTF-8?q?/=EB=9D=BC=EC=9D=B4=ED=8A=B8=20=EC=9E=89=ED=81=AC=20=EB=B0=98?= =?UTF-8?q?=EC=A0=84=EC=9C=BC=EB=A1=9C=20=ED=95=84=EA=B8=B0=EA=B0=80=20?= =?UTF-8?q?=EC=95=88=20=EB=B3=B4=EC=9D=B4=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EC=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PencilKit은 획 색을 화면 모드에 맞춰 자동 반전하는데, 양식(PDF·사진)은 항상 밝은 배경이라 다크 모드 아이패드에서 쓴 획이 라이트 모드 맥의 흰 양식 위에서 흰색으로 반전돼 보이지 않았다(동기화 문제로 오인된 실사용 보고). - 양식 페이지는 캔버스 overrideUserInterfaceStyle + PKToolPicker colorUserInterfaceStyle을 .light로 고정 (해석·렌더를 같은 기준으로 묶는 WYSIWYG) - 양식 없는 페이지는 기존 동적 반전 유지 (다크 배경 종이에선 그게 맞음) - 내보내기 PKDrawing.image도 라이트 트레잇 고정 — 호출 시점 트레잇 의존이라 다크에서 내보내면 획이 반전 렌더될 수 있던 잠재 결함 제거 - 도움말 '나만의 양식(속지)' 문구 갱신 + en/ja 번역 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01NNxA172hNDRpDsJ2qztKPf --- myApp/HaruDanim/CLAUDE.md | 3 +- myApp/HaruDanim/IOS/Localizable.xcstrings | 32 +++++++++---------- .../IOS/Views/DiaryExportSheet.swift | 7 +++- myApp/HaruDanim/IOS/Views/DiaryNotePage.swift | 26 ++++++++++++++- myApp/HaruDanim/IOS/Views/HelpView.swift | 2 +- 5 files changed, 50 insertions(+), 20 deletions(-) diff --git a/myApp/HaruDanim/CLAUDE.md b/myApp/HaruDanim/CLAUDE.md index 2aae210..ff2f7e1 100644 --- a/myApp/HaruDanim/CLAUDE.md +++ b/myApp/HaruDanim/CLAUDE.md @@ -18,7 +18,7 @@ | 번들 ID | `com.yechan.HaruDanim` / App Group `group.com.yechan.HaruDanim` / CloudKit `iCloud.com.yechan.HaruDanim` | | 수익 모델 | 부분 유료화. 무료 한도(행동 10·목표 2·목표당 다짐 3) + 프리미엄 결제 시 해제 | | 결제 상품 | `com.yechan.HaruDanim.premium.monthly`(월 4,400원) / `.yearly`(년 44,000원) / `.lifetime`(77,000원) — **ASC 등록·판매 중(실제 가격, 2026-07-28)**. 로컬 테스트 구성(HaruDanim.storekit)도 동일 가격. 가격은 코드에 없고 `product.displayPrice`로 동적 표기, 년 구독 절약률 배지도 동적 계산 | -| 현재 상태 (2026-08-02) | **버전 1.2 App Store 출시 완료(2026-08-02, 사용자 확인) — 유지보수 모드. 1.3 또는 메이저 업데이트 준비 대기 상태**(사용자의 버그 보고·기능 요청을 받아 진행). 1.2 내용: 주기 몫 완료 상태 표기(§4.2)+도움말 '진행률 읽는 법' 갱신(상세는 아래 소기능 이력). **버전 1.1 출시 2026-07-30.** 1.1 내용: ①**맥 일기 개방**(§6.7 — 사이드바 노출 + '그리기' 토글로 마우스 필기, 텍스트 우선 도구줄. 아이패드 경로 불변. 맥 실기 확인 완료) ②**CSV 가져오기**(§6.8 — 프리미엄, 추가 전용·미리 보기·멱등. 검증 `-csvImportTest` 20건 ALL PASS) ③**일기 기본 표시 설정**(§6.7 — 캘린더·목표·행동 전 날짜 기본값 + 날짜별 재정의, 스키마 무변경 마커 방식) ④**'짧은 기록 무시' iCloud KVS 동기화**(§6.8 — 전 기기 공통) ⑤스크린샷 전면 개편(아이폰 10·아이패드 10·워치 합성 1 × ko/en/ja — ASC 업로드 완료) ⑥스토어 메타데이터 변경(앱 이름·부제목·키워드·프로모션 — 검색·색인 강화, `Marketing/AppStore/app-name-subtitle.txt`·`keywords.txt`·`promotional-text.txt`. 스토어 표기만 변경, 설치 이름 불변) ⑦MARKETING_VERSION 1.1. **버전 1.0 출시 2026-07-28.** 이후 작업은 사용자 실사용 중 발견한 버그 수정·사용자가 원하는 소기능 추가만 한다(선제적 기능 제안·대규모 리팩터링 금지). 출시 후 소기능 이력: **주기 몫 완료 상태 표기**(2026-08-01, 사용자 요청 — §4.2. 도움말 '진행률 읽는 법' 문구도 갱신. 같은 날 MARKETING_VERSION 1.2(빌드 1)로 상향 + `Marketing/AppStore/whats-new-1.2.txt` 작성·TestFlight 업로드, **심사 통과 → App Store 출시 완료(2026-08-02, 사용자 확인)**). 업데이트 제출: 버전 올려 빌드 업로드 → 심사 제출(IAP는 첫 심사에서 승인됐으므로 첨부 불필요). 출시 전 이력 — RC는 커밋 `f05e611`(버전 1.0 (1)), 이후 실사용 보고 기반 수정 라운드(전부 커밋·푸시·실기기 확인 완료): l10n 누락 일괄·ja 앱 이름 'Haru Danim' 통일·워치 컴플리케이션 추천 캡 제거(§11)·⑥ 위젯 종료 버튼(§10)·진행률 환산 캡+수행일 집계+수행일 아님 표기(§4.2)·파일명/CSV 헤더 현지화(§7)·워치 컴플리케이션 목표 필터(§6.4·§11, 사용자 승인 소기능)·기록 시각 입력 상시 휠 다이얼+분 절사(§6.5)·일기 달력 기분 사진 백레이어(§6.7)·다짐 없는 목표 '다짐 없음' 표기(§4.3)·워치 측정 중 행 탭 종료(§11)·도움말 예시 스크린샷 18장(§6.8)·설정 하루 시작 시간 접힘 행(§6.5)·**모음 탭 즐겨찾기 모아 보기**(§6.1 — 행동 많아질 때 혼잡도 대응, 사용자 승인 소기능. v1 별도 카드 가로 줄[대안 A~F 중 A]이 "따로 노는 느낌" 실사용 피드백으로 v2 그리드 섹션 통합+나머지 접기로 교체, 같은 날 후속 피드백으로 편집 모드 섹션 인지·섹션 간 드래그 지정/해제·"지정 순서대로 뒤에" 규칙 추가, 2026-07-22)·**en 복수형 정리**(2026-07-22 — 수량 1일 때 "1 times/quests" 류 오류를 카탈로그 plural variation으로 14건 전환[iOS 10·위젯 3·워치 1], 모음 탭 섹션 제목 en "Favorite"→"Favorites"로 워치와 통일. ko/ja 무영향). **App Store 등록 자료는 `Marketing/`에 완비**(설명·키워드·구독 메타·스크린샷 원본/합성판, README에 재생성 절차 — 앱 변경이 자료에 영향 주면 요청 없이 함께 갱신할 것. 2026-07-22 즐겨찾기 섹션(v2) 반영해 아이폰·아이패드 01-main과 help-main ko/en/ja 재촬영·합성판 재생성. **2026-07-29 스크린샷 세트 확장** — 아이폰 8장(+위젯·버블 메뉴·iCloud 동기화 합성·다크 모드)/아이패드 7장(+주간 타임테이블·위젯·동기화 합성) × ko/en/ja, 촬영·합성 절차는 Marketing/README '추가 스크린샷' 절. **1.1 제출 때 ASC 업로드 완료**). **사업자 등록·통신판매업 신고 완료(2026-07-22)** — 서류 절차 끝, ASC 등록·유료 계약 진행 가능(순서는 Marketing/README 체크리스트). 사용자는 계속 실사용 테스트 중이며 버그 보고 시: 최소 변경 + 시뮬레이터 재검증 + l10n 루틴(§2.3) + Debug/Store(워치 파일이면 워치까지) 빌드 + 커밋·푸시 | +| 현재 상태 (2026-08-02) | **버전 1.2 App Store 출시 완료(2026-08-02, 사용자 확인) — 유지보수 모드. 1.3 또는 메이저 업데이트 준비 대기 상태**(사용자의 버그 보고·기능 요청을 받아 진행). 1.2 내용: 주기 몫 완료 상태 표기(§4.2)+도움말 '진행률 읽는 법' 갱신(상세는 아래 소기능 이력). **버전 1.1 출시 2026-07-30.** 1.1 내용: ①**맥 일기 개방**(§6.7 — 사이드바 노출 + '그리기' 토글로 마우스 필기, 텍스트 우선 도구줄. 아이패드 경로 불변. 맥 실기 확인 완료) ②**CSV 가져오기**(§6.8 — 프리미엄, 추가 전용·미리 보기·멱등. 검증 `-csvImportTest` 20건 ALL PASS) ③**일기 기본 표시 설정**(§6.7 — 캘린더·목표·행동 전 날짜 기본값 + 날짜별 재정의, 스키마 무변경 마커 방식) ④**'짧은 기록 무시' iCloud KVS 동기화**(§6.8 — 전 기기 공통) ⑤스크린샷 전면 개편(아이폰 10·아이패드 10·워치 합성 1 × ko/en/ja — ASC 업로드 완료) ⑥스토어 메타데이터 변경(앱 이름·부제목·키워드·프로모션 — 검색·색인 강화, `Marketing/AppStore/app-name-subtitle.txt`·`keywords.txt`·`promotional-text.txt`. 스토어 표기만 변경, 설치 이름 불변) ⑦MARKETING_VERSION 1.1. **버전 1.0 출시 2026-07-28.** 이후 작업은 사용자 실사용 중 발견한 버그 수정·사용자가 원하는 소기능 추가만 한다(선제적 기능 제안·대규모 리팩터링 금지). 출시 후 소기능 이력: **양식 페이지 펜 색 고정**(2026-08-03, 사용자 요청 — §6.7. 다크/라이트 잉크 반전으로 맥·아이패드에서 필기가 안 보이던 실사용 보고 해소, 내보내기 라이트 트레잇 고정 포함)·**주기 몫 완료 상태 표기**(2026-08-01, 사용자 요청 — §4.2. 도움말 '진행률 읽는 법' 문구도 갱신. 같은 날 MARKETING_VERSION 1.2(빌드 1)로 상향 + `Marketing/AppStore/whats-new-1.2.txt` 작성·TestFlight 업로드, **심사 통과 → App Store 출시 완료(2026-08-02, 사용자 확인)**). 업데이트 제출: 버전 올려 빌드 업로드 → 심사 제출(IAP는 첫 심사에서 승인됐으므로 첨부 불필요). 출시 전 이력 — RC는 커밋 `f05e611`(버전 1.0 (1)), 이후 실사용 보고 기반 수정 라운드(전부 커밋·푸시·실기기 확인 완료): l10n 누락 일괄·ja 앱 이름 'Haru Danim' 통일·워치 컴플리케이션 추천 캡 제거(§11)·⑥ 위젯 종료 버튼(§10)·진행률 환산 캡+수행일 집계+수행일 아님 표기(§4.2)·파일명/CSV 헤더 현지화(§7)·워치 컴플리케이션 목표 필터(§6.4·§11, 사용자 승인 소기능)·기록 시각 입력 상시 휠 다이얼+분 절사(§6.5)·일기 달력 기분 사진 백레이어(§6.7)·다짐 없는 목표 '다짐 없음' 표기(§4.3)·워치 측정 중 행 탭 종료(§11)·도움말 예시 스크린샷 18장(§6.8)·설정 하루 시작 시간 접힘 행(§6.5)·**모음 탭 즐겨찾기 모아 보기**(§6.1 — 행동 많아질 때 혼잡도 대응, 사용자 승인 소기능. v1 별도 카드 가로 줄[대안 A~F 중 A]이 "따로 노는 느낌" 실사용 피드백으로 v2 그리드 섹션 통합+나머지 접기로 교체, 같은 날 후속 피드백으로 편집 모드 섹션 인지·섹션 간 드래그 지정/해제·"지정 순서대로 뒤에" 규칙 추가, 2026-07-22)·**en 복수형 정리**(2026-07-22 — 수량 1일 때 "1 times/quests" 류 오류를 카탈로그 plural variation으로 14건 전환[iOS 10·위젯 3·워치 1], 모음 탭 섹션 제목 en "Favorite"→"Favorites"로 워치와 통일. ko/ja 무영향). **App Store 등록 자료는 `Marketing/`에 완비**(설명·키워드·구독 메타·스크린샷 원본/합성판, README에 재생성 절차 — 앱 변경이 자료에 영향 주면 요청 없이 함께 갱신할 것. 2026-07-22 즐겨찾기 섹션(v2) 반영해 아이폰·아이패드 01-main과 help-main ko/en/ja 재촬영·합성판 재생성. **2026-07-29 스크린샷 세트 확장** — 아이폰 8장(+위젯·버블 메뉴·iCloud 동기화 합성·다크 모드)/아이패드 7장(+주간 타임테이블·위젯·동기화 합성) × ko/en/ja, 촬영·합성 절차는 Marketing/README '추가 스크린샷' 절. **1.1 제출 때 ASC 업로드 완료**). **사업자 등록·통신판매업 신고 완료(2026-07-22)** — 서류 절차 끝, ASC 등록·유료 계약 진행 가능(순서는 Marketing/README 체크리스트). 사용자는 계속 실사용 테스트 중이며 버그 보고 시: 최소 변경 + 시뮬레이터 재검증 + l10n 루틴(§2.3) + Debug/Store(워치 파일이면 워치까지) 빌드 + 커밋·푸시 | | 출시·운영 메모 (2026-07-28) | **ASC 등록·심사·출시 전부 완료** — 제출 1건에 앱 1.0+구독 그룹+상품 3종 동반(신형 ASC는 각 항목의 "심사에 추가"로 하나의 제출 초안에 담는 방식), '앱 개인정보 보호'="데이터 수집 안 함", 유료 앱 계약·대한민국 세금 양식 활성, 소규모 사업자 프로그램 가입. 개발자 본인 프리미엄은 **평생 이용권 특가 코드(무료 Offer Code) 교환**으로 스토어 버전에 적용됨(IAP용 프로모션 코드는 2026-03 폐지 — 이후 무료 지급은 특가 코드만 가능, 생성 후 교환 가능까지 최대 1시간). 상시 참고: `ITSAppUsesNonExemptEncryption=NO`, PrivacyInfo.xcprivacy 4개 번들(수집·트래킹 없음), 개인정보처리방침=`github.com/notalentprogrammer/HaruDanim` PRIVACY.md·이용약관=Apple 표준 EULA(결제 화면·앱 설명 모두 링크). **iCloud 프로덕션 동기화 확인 완료(2026-07-28)** — 아이폰·아이패드·맥 3기기 반나절 실사용에서 기존 데이터 포함 정상 왕복(개발→프로덕션 CloudKit 환경 전환에 따른 재업로드 우려 해소. 향후 동기화 문제 보고 시 이 전환 이력 참고). 예정: 정산 계좌 변경(시기 무관, 예금주 명의 일치·지급 회차 밀림 고지 확인). 절차 상세 기록은 Marketing/README.md 체크리스트 | --- @@ -233,6 +233,7 @@ xcrun xcstringstool sync Widgets/Localizable.xcstrings --stringsdata "${widget_f - **기본 표시 설정**(1.1 — 달력 툴바 slider 아이콘, `DiaryDefaultsSheet`): 캘린더 일정 기본 모드(표시 안 함/모든 캘린더/선택한 캘린더만)·목표 기본 숨김·타임테이블 행동 기본 숨김을 **기기 로컬**(standard `diary.default*` — diary.section*과 같은 계층)로 저장해 모든 날짜에 적용. **날짜별 재정의는 기존 동기화 배열에 마커 문자열 `#override`(`DiaryDefaults.overrideMarker`)를 함께 저장** — 스키마 무변경, 구버전(1.0/1.1)은 마커가 어떤 uuid·이벤트 id와도 매칭되지 않아 표시 결과 동일, 마커 없는 비어 있지 않은 목록(1.1 이전 날짜별 선택)은 재정의로 계속 존중. 효과 계산은 `DiaryDefaults.effective*` 단일 지점(요약 화면·내보내기·캘린더 블록 공유). 각 날짜 필터 시트에 '기본값으로 되돌리기'(재정의 삭제 → 기본값 복귀). 행동 필터의 onChange는 **효과값과 같으면 저장하지 않음** — 시트를 열기만 해도 기본값이 재정의로 굳는 것 방지. '모든 캘린더' 모드는 그날 일정을 실시간 계산하므로 새 일정도 자동 반영 - **일기 잠금**(설정 → 일기, 아이패드·맥 표시 — 2026-07-23, 1.1에서 맥 포함): 켜면 일기 탭 진입 시 `DiaryLockGateView`가 전체를 가리고 `DiaryLock`(.deviceOwnerAuthentication — Face ID/Touch ID/Optic ID+암호 폴백을 시스템이 자동 처리)으로 해제. 백그라운드 진입 시 재잠금(App scenePhase), 설정 토글은 켜고 끌 때 모두 인증 요구, 잠글 수단이 없는 기기(암호 미설정)는 통과(영구 잠김 방지). 키 `diary.lockEnabled`(standard — 기기 로컬), `NSFaceIDUsageDescription` 필수(IOS/Info.plist+InfoPlist.xcstrings) - **프리미엄 만료 열람 모드**: 이미 쓴 일기(hasContent)가 있으면 잠금 화면 대신 달력을 열람 전용으로 연다 — 배너 + 일기 있는 날짜만 활성, `environment(\.diaryReadOnly)`로 전 화면의 편집 UI(기분/할일/필기/필터/캘린더/⋯메뉴) 비활성, 열람 진입은 엔트리를 생성하지 않음. 일기를 쓴 적 없으면 기존 잠금 안내 +- **양식 페이지 펜 색 고정(2026-08-03, 사용자 요청)**: 양식이 깔린 페이지(`template != nil`)는 캔버스 `overrideUserInterfaceStyle`과 `PKToolPicker.colorUserInterfaceStyle`을 `.light`로 고정 — PencilKit의 다크/라이트 잉크 자동 반전 때문에 다크 모드 아이패드에서 쓴 획이 라이트 모드 맥의 흰 양식 위에서 흰색으로 반전돼 안 보이던 실사용 보고의 해소(동기화 문제로 오인됐던 건). 팔레트 색 해석까지 함께 고정해야 WYSIWYG(트레잇만 고정하면 다크에서 고른 '검정'이 흰 획으로 저장되는 반전이 남음). 고정 이전에 다크에서 쓴 기존 획은 라이트 기준 색 그대로(흰색)라 계속 안 보임 — 데이터 무변경, 사용자 인지 완료. 양식 없는 페이지는 기존 동적 반전 유지(다크 배경 종이에선 그게 맞음). 내보내기의 `PKDrawing.image`도 라이트 트레잇으로 고정(전 페이지 공통 — 호출 시점 트레잇 의존이라 다크에서 내보내면 획이 반전 렌더될 수 있던 잠재 결함 제거, 인쇄 페이지는 원래 라이트 고정이라 화면과 일치) - **양식(속지)** (`DiaryTemplates.swift`): 달력 툴바 '양식 관리'에서 PDF(≤20MB)·사진을 가져와 라이브러리로 관리. 페이지 추가 시 [빈 캔버스/줄 노트/내 양식] 선택(양식 0개면 시트 없이 기존처럼 즉시 추가), 여러 쪽 PDF는 2단계 쪽 썸네일 선택(최대 24쪽, 원본은 통째 1개 저장 + 쪽 인덱스 참조). 렌더: 페이지 논리 크기에 aspect-fit(좌표계 불변), **PDF는 줌 종료 시 현재 배율로 백그라운드 재래스터**(`DiaryTemplateImageView` — 펜슬 캔버스 선명도 훅에 함께 연결), 이미지는 가져올 때 긴 변 3072px 리샘플(필기 래스터 상한 3×와 동일 → 흐림 없음). 양식 페이지에선 줄 노트 토글 숨김. 양식 삭제 시 사용 중 페이지 수 경고 → 해당 페이지는 빈 캔버스 폴백(필기·요소 보존). 내보내기에도 동일 반영 - 노트 페이지: 768×1024 논리 좌표 고정 + scaleEffect. 배치 요소: 사진·도형(사각/원/화살표/선)·**텍스트 상자**(키보드 입력, 배치 모드에서 '글 수정'으로 내용·색 편집). ⋯ 메뉴 '페이지 순서 변경'으로 노트 페이지 드래그 재배열(요약은 항상 첫 장). **실기기 필기는 펜슬 전용, 손가락은 이동/줌만**(시뮬레이터는 anyInput). 핀치줌 최대 4배, `SharpPencilCanvasView`가 줌에 맞춰 래스터 배율 유지(획 선명도). ⚠️ 배율 적용은 **뷰의 contentScaleFactor만** — 서브레이어 contentsScale+setNeedsDisplay를 직접 건드리면 PencilKit 획 타일 픽셀이 지워진 채 재렌더되지 않아 확대 시 필기가 사라진다(수정된 버그). 줄 노트(간격 4단계)·사진·도형(사각/원/화살표/선) 배치 모드(드래그·핀치 크기 조절, 저장은 비율 좌표) diff --git a/myApp/HaruDanim/IOS/Localizable.xcstrings b/myApp/HaruDanim/IOS/Localizable.xcstrings index 0571a55..29aa000 100644 --- a/myApp/HaruDanim/IOS/Localizable.xcstrings +++ b/myApp/HaruDanim/IOS/Localizable.xcstrings @@ -970,12 +970,6 @@ }, "'%@ · %@' 이번 달 몫은 이미 채웠어요. 오늘은 더 하지 않아도 돼요." : { "localizations" : { - "ko" : { - "stringUnit" : { - "state" : "new", - "value" : "'%1$@ · %2$@' 이번 달 몫은 이미 채웠어요. 오늘은 더 하지 않아도 돼요." - } - }, "en" : { "stringUnit" : { "state" : "translated", @@ -987,17 +981,17 @@ "state" : "translated", "value" : "「%1$@ · %2$@」は今月の分をすでに達成しています。今日はやらなくても大丈夫です。" } + }, + "ko" : { + "stringUnit" : { + "state" : "new", + "value" : "'%1$@ · %2$@' 이번 달 몫은 이미 채웠어요. 오늘은 더 하지 않아도 돼요." + } } } }, "'%@ · %@' 이번 주 몫은 이미 채웠어요. 오늘은 더 하지 않아도 돼요." : { "localizations" : { - "ko" : { - "stringUnit" : { - "state" : "new", - "value" : "'%1$@ · %2$@' 이번 주 몫은 이미 채웠어요. 오늘은 더 하지 않아도 돼요." - } - }, "en" : { "stringUnit" : { "state" : "translated", @@ -1009,6 +1003,12 @@ "state" : "translated", "value" : "「%1$@ · %2$@」は今週の分をすでに達成しています。今日はやらなくても大丈夫です。" } + }, + "ko" : { + "stringUnit" : { + "state" : "new", + "value" : "'%1$@ · %2$@' 이번 주 몫은 이미 채웠어요. 오늘은 더 하지 않아도 돼요." + } } } }, @@ -4316,18 +4316,18 @@ } } }, - "달력 화면 오른쪽 위 양식 버튼에서 PDF나 사진을 노트 배경 양식으로 가져올 수 있어요. 가져온 양식은 페이지를 추가할 때 빈 캔버스·줄 노트와 함께 고를 수 있고, 여러 쪽 PDF는 원하는 쪽을 골라 써요. 양식은 필기 아래에 깔리고 확대해도 선명하게 보여요. 양식을 삭제하면 그 양식을 쓰던 페이지는 빈 캔버스로 표시되지만 필기는 그대로 남아요." : { + "달력 화면 오른쪽 위 양식 버튼에서 PDF나 사진을 노트 배경 양식으로 가져올 수 있어요. 가져온 양식은 페이지를 추가할 때 빈 캔버스·줄 노트와 함께 고를 수 있고, 여러 쪽 PDF는 원하는 쪽을 골라 써요. 양식은 필기 아래에 깔리고 확대해도 선명하게 보여요. 양식을 삭제하면 그 양식을 쓰던 페이지는 빈 캔버스로 표시되지만 필기는 그대로 남아요.\n양식이 깔린 페이지에서는 펜 색이 화면 모드(라이트·다크)와 상관없이 고른 색 그대로 고정돼요 — 양식은 항상 밝은 배경이라, 어떤 기기·모드에서 봐도 필기가 같은 색으로 보여요." : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Use the templates button at the top right of the calendar screen to import PDFs or photos as note background templates. When adding a page, you can choose an imported template alongside the blank canvas and lined paper, and for multi-page PDFs you pick the page you want. Templates sit underneath your handwriting and stay sharp even when zoomed in. If you delete a template, pages that used it show as a blank canvas, but your handwriting is kept." + "value" : "Use the templates button at the top right of the calendar screen to import PDFs or photos as note background templates. When adding a page, you can choose an imported template alongside the blank canvas and lined paper, and for multi-page PDFs you pick the page you want. Templates sit underneath your handwriting and stay sharp even when zoomed in. If you delete a template, pages that used it show as a blank canvas, but your handwriting is kept.\nOn pages with a template, pen colors stay exactly as you picked them regardless of Light or Dark Mode — templates always have a bright background, so your handwriting looks the same color on every device and in every mode." } }, "ja" : { "stringUnit" : { "state" : "translated", - "value" : "カレンダー画面右上のテンプレートボタンから、PDFや写真をノートの背景テンプレートとして読み込めます。ページを追加するとき、白紙・罫線ノートと一緒に読み込んだテンプレートを選べ、複数ページのPDFは使いたいページを選びます。テンプレートは手書きの下に敷かれ、拡大しても鮮明に表示されます。テンプレートを削除しても、使っていたページは白紙として表示されるだけで、手書きはそのまま残ります。" + "value" : "カレンダー画面右上のテンプレートボタンから、PDFや写真をノートの背景テンプレートとして読み込めます。ページを追加するとき、白紙・罫線ノートと一緒に読み込んだテンプレートを選べ、複数ページのPDFは使いたいページを選びます。テンプレートは手書きの下に敷かれ、拡大しても鮮明に表示されます。テンプレートを削除しても、使っていたページは白紙として表示されるだけで、手書きはそのまま残ります。\nテンプレートが敷かれたページでは、ライト・ダークモードに関係なくペンの色が選んだ色のまま固定されます — テンプレートは常に明るい背景なので、どの端末・モードで見ても手書きが同じ色で表示されます。" } } } @@ -14431,4 +14431,4 @@ } }, "version" : "1.0" -} \ No newline at end of file +} diff --git a/myApp/HaruDanim/IOS/Views/DiaryExportSheet.swift b/myApp/HaruDanim/IOS/Views/DiaryExportSheet.swift index b4bce47..e7282f3 100644 --- a/myApp/HaruDanim/IOS/Views/DiaryExportSheet.swift +++ b/myApp/HaruDanim/IOS/Views/DiaryExportSheet.swift @@ -282,7 +282,12 @@ struct DiaryExportSheet: View { let size = DiaryPageMetrics.size var drawingImage: UIImage? if !page.drawingData.isEmpty, let drawing = try? PKDrawing(data: page.drawingData) { - drawingImage = drawing.image(from: CGRect(origin: .zero, size: size), scale: 2) + // 인쇄 페이지는 라이트 고정(흰 종이)이라 획 색도 라이트 기준으로 못 박는다 — + // PKDrawing.image는 호출 시점의 현재 트레잇을 따르므로, 고정하지 않으면 + // 다크 모드에서 내보낼 때 획이 반전된 색(흰색)으로 렌더될 수 있다 + UITraitCollection(userInterfaceStyle: .light).performAsCurrent { + drawingImage = drawing.image(from: CGRect(origin: .zero, size: size), scale: 2) + } } // 배경 양식도 화면과 동일하게 담는다 (양식이 삭제됐으면 화면처럼 빈 캔버스) var templateImage: UIImage? diff --git a/myApp/HaruDanim/IOS/Views/DiaryNotePage.swift b/myApp/HaruDanim/IOS/Views/DiaryNotePage.swift index 731aa76..4e477cc 100644 --- a/myApp/HaruDanim/IOS/Views/DiaryNotePage.swift +++ b/myApp/HaruDanim/IOS/Views/DiaryNotePage.swift @@ -267,7 +267,8 @@ struct DiaryNotePageView: View { // drawMode는 맥에서만 꺼질 수 있다(아이패드 항상 true — 기존 동작 불변, §6.7) DiaryPencilCanvas( drawingData: page.drawingData, - isActive: isActive && !arranging && !readOnly && drawMode + isActive: isActive && !arranging && !readOnly && drawMode, + fixedLightInk: template != nil ) { data in page.drawingData = data save() @@ -721,6 +722,12 @@ struct DiaryPencilCanvas: UIViewRepresentable { let drawingData: Data /// 퍼스트 리스폰더(펜슬 도구 팔레트) 보유 여부 — 보이는 페이지 & 필기 모드일 때만 let isActive: Bool + /// 양식(PDF·사진) 페이지는 펜 색을 라이트 모드 기준으로 고정한다. + /// PencilKit은 기본적으로 획 색을 다크/라이트에 맞춰 자동 반전하는데, 양식은 항상 + /// 밝은 배경(흰 PDF 등)이라 다크 모드 기기에서 쓴 획이 라이트 모드 기기에서 + /// 흰색으로 반전돼 보이지 않는 문제가 있었다(맥·아이패드 모드가 다를 때 실사용 보고). + /// 색 고정은 캔버스 트레잇 + 도구 팔레트 색 해석을 함께 묶어야 WYSIWYG가 된다. + let fixedLightInk: Bool let onChange: (Data) -> Void func makeCoordinator() -> Coordinator { @@ -731,6 +738,7 @@ struct DiaryPencilCanvas: UIViewRepresentable { let canvas = SharpPencilCanvasView() canvas.backgroundColor = .clear canvas.isOpaque = false + canvas.overrideUserInterfaceStyle = fixedLightInk ? .light : .unspecified #if targetEnvironment(simulator) // 시뮬레이터에는 펜슬이 없으므로 마우스(손가락) 입력 허용 canvas.drawingPolicy = .anyInput @@ -749,6 +757,12 @@ struct DiaryPencilCanvas: UIViewRepresentable { } func updateUIView(_ canvas: SharpPencilCanvasView, context: Context) { + // 양식이 늦게 동기화로 도착하거나 삭제되면 페이지가 살아 있는 채로 값이 바뀔 수 있다 + let style: UIUserInterfaceStyle = fixedLightInk ? .light : .unspecified + if canvas.overrideUserInterfaceStyle != style { + canvas.overrideUserInterfaceStyle = style + } + context.coordinator.setFixedLightInk(fixedLightInk) context.coordinator.setActive(isActive) } @@ -763,6 +777,16 @@ struct DiaryPencilCanvas: UIViewRepresentable { self.onChange = onChange } + /// 양식 페이지에서는 팔레트가 고른 색도 라이트 기준으로 해석·저장되게 한다 — + /// 캔버스 트레잇만 고정하면 다크 모드에서 고른 '검정'이 흰색 획으로 저장되던 + /// 반전이 그대로 남는다 (해석과 렌더를 같은 기준으로 묶는 핵심) + func setFixedLightInk(_ fixed: Bool) { + let style: UIUserInterfaceStyle = fixed ? .light : .unspecified + if toolPicker.colorUserInterfaceStyle != style { + toolPicker.colorUserInterfaceStyle = style + } + } + func setActive(_ active: Bool) { guard let canvas else { return } if active { diff --git a/myApp/HaruDanim/IOS/Views/HelpView.swift b/myApp/HaruDanim/IOS/Views/HelpView.swift index 49301ad..958c967 100644 --- a/myApp/HaruDanim/IOS/Views/HelpView.swift +++ b/myApp/HaruDanim/IOS/Views/HelpView.swift @@ -320,7 +320,7 @@ struct HelpView: View { HelpTopic( symbol: "doc.text.image", title: "나만의 양식(속지)", - body: "달력 화면 오른쪽 위 양식 버튼에서 PDF나 사진을 노트 배경 양식으로 가져올 수 있어요. 가져온 양식은 페이지를 추가할 때 빈 캔버스·줄 노트와 함께 고를 수 있고, 여러 쪽 PDF는 원하는 쪽을 골라 써요. 양식은 필기 아래에 깔리고 확대해도 선명하게 보여요. 양식을 삭제하면 그 양식을 쓰던 페이지는 빈 캔버스로 표시되지만 필기는 그대로 남아요." + body: "달력 화면 오른쪽 위 양식 버튼에서 PDF나 사진을 노트 배경 양식으로 가져올 수 있어요. 가져온 양식은 페이지를 추가할 때 빈 캔버스·줄 노트와 함께 고를 수 있고, 여러 쪽 PDF는 원하는 쪽을 골라 써요. 양식은 필기 아래에 깔리고 확대해도 선명하게 보여요. 양식을 삭제하면 그 양식을 쓰던 페이지는 빈 캔버스로 표시되지만 필기는 그대로 남아요.\n양식이 깔린 페이지에서는 펜 색이 화면 모드(라이트·다크)와 상관없이 고른 색 그대로 고정돼요 — 양식은 항상 밝은 배경이라, 어떤 기기·모드에서 봐도 필기가 같은 색으로 보여요." ), HelpTopic( symbol: "square.and.arrow.up.on.square",