fix(main): 새로고침 버튼 프리미엄 판정을 RefreshButton body 안으로 이동

- .toolbar { if PremiumManager.shared.isPremium } 조건은 @Observable 변경 시
  재평가가 보장되지 않아, 실행 중 프리미엄 전환(설정 테스트 토글·구매) 후
  버튼이 앱 재시작 전까지 나타나지 않는 실기기 결함 (아이폰·아이패드·맥 공통)
- ToolbarItem은 무조건 두고 RefreshButton body에서 판정 — View body는
  관찰 추적이 확실 (같은 body의 isRefreshing 전환이 검증된 패턴)
- 검증: Debug·Store 빌드, 무료(버튼 없음)/프리미엄(버튼 표시) 아이폰·아이패드 캡처

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
songyc macbook 2026-07-23 21:54:11 +09:00
parent 06b42118c9
commit 6b5e1dc20a
3 changed files with 22 additions and 18 deletions

View File

@ -183,7 +183,7 @@ xcrun xcstringstool sync Widgets/Localizable.xcstrings --stringsdata "${widget_f
- **행동이 많아질 때의 혼잡도 문제**(2026-07-21 실사용 피드백): 22개 시드로 iPhone(3열·6열)·iPad·맥 4가지를 직접 시뮬레이션해 6가지 대안(A~F)을 검토 — 구현된 즐겨찾기 모아 보기(A, 현재는 v2 섹션형+나머지 접기)에 더해, 향후 후보로 ⓑ꼬리표별 접기(출시 후), ⓒ검색/필터(출시 후), ⓓ한 줄 개수 늘릴 때 경고 문구(미착수, 저위험)가 있음. **명시적으로 기각**: 즐겨찾기 등을 전체 그리드에서 숨기는 옵트인 방식(행동이 눌러도 안 보이게 될 위험 > 이득) — 다시 제안하지 말 것
- 배치 편집: **편집 모드도 즐겨찾기/나머지 섹션 구조 그대로**(항상 펼침·접기 버튼 없음 — "편집이 즐겨찾기 없다고 가정한다"는 2026-07-22 후속 피드백 해소). 섹션 안 드래그=순서 변경(실시간, 전역 `local.actionOrder` 하나에 반영 — CloudKit 모델에 쓰지 않음), **섹션 사이 드래그=즐겨찾기 지정·해제**(`commitDrop` — 드롭 확정 시점에만 처리. 호버 중 교차 이동은 소속이 안 바뀐 채 전역 순서만 바뀌어 자기 섹션 안에서 점프해 보이므로 `moveDragging`이 무시). **빈 섹션은 점선 드롭 존**(`favoriteDropZone`+`FavoriteZoneDropDelegate`, 호버 하이라이트)이 받아 즐겨찾기 0개여도 끌어서 지정 가능. 지글 애니메이션 유지, isFavorite 변경은 모델 필드라 `DataChange.commit` 경유(워치 즐겨찾기·위젯 갱신)
- "짧은 기록 무시"(minSessionSeconds): 설정보다 짧은 세션은 종료 시 삭제. 메모 창 옵션 켠 행동은 종료/+1 시 메모 시트(건너뛰기 가능)
- 툴바: 새로고침(좌 — **프리미엄일 때만 표시**: 쓰임새인 iCloud 반영·위젯/워치 갱신이 전부 프리미엄이라 무료에선 숨김, 도움말에도 명시. 2026-07-23) / 배치 편집(우)
- 툴바: 새로고침(좌 — **프리미엄일 때만 표시**: 쓰임새인 iCloud 반영·위젯/워치 갱신이 전부 프리미엄이라 무료에선 숨김, 도움말에도 명시. **판정은 RefreshButton body 안에서** — MainView .toolbar의 `if`@Observable 변경 시 재평가가 보장되지 않아 실행 중 프리미엄 전환 후 버튼이 재시작 전까지 안 나타나던 실기기 결함의 수정, 2026-07-23) / 배치 편집(우)
- 빈 상태(행동 0개): 개념 한 줄 소개 + '첫 행동 만들기'(추가 시트 직행) + '예시 행동으로 시작해 보기'(꼬리표 생활·건강 + 독서/운동/물 마시기 생성)
### 6.2 행동 탭 (`ActionViews`)

View File

@ -50,22 +50,27 @@ import SwiftUI
/// .
/// (iCloud ·/ )
///
/// .
/// body MainView .toolbar { if ... }
/// @Observable , ( ·)
/// (2026-07-23)
struct RefreshButton: View {
private let refresh = AppRefresh.shared
var body: some View {
Button {
refresh.refreshNow()
} label: {
if refresh.isRefreshing {
ProgressView()
} else {
Image(systemName: "arrow.clockwise")
if PremiumManager.shared.isPremium {
Button {
refresh.refreshNow()
} label: {
if refresh.isRefreshing {
ProgressView()
} else {
Image(systemName: "arrow.clockwise")
}
}
.disabled(refresh.isRefreshing)
.accessibilityLabel(Text("새로고침"))
.accessibilityHint(Text("다른 기기에서 바뀐 내용을 다시 불러오고 위젯도 갱신해요"))
}
.disabled(refresh.isRefreshing)
.accessibilityLabel(Text("새로고침"))
.accessibilityHint(Text("다른 기기에서 바뀐 내용을 다시 불러오고 위젯도 갱신해요"))
}
}

View File

@ -103,12 +103,11 @@ struct MainView: View {
.background(AppTheme.background)
.navigationTitle("모음")
.toolbar {
if PremiumManager.shared.isPremium {
ToolbarItem(placement: .topBarLeading) {
// .
// iCloud ··
RefreshButton()
}
ToolbarItem(placement: .topBarLeading) {
// .
// RefreshButton body
// toolbar if @Observable (AppRefresh.swift )
RefreshButton()
}
ToolbarItem(placement: .topBarTrailing) {
Button(isEditing ? String(localized: "완료") : String(localized: "배치 편집")) {