fix(ipad): unify action button heights across tracking types

- 실사용 보고: 아이패드 모음 탭에서 시간형·횟수형 행동 버튼 높이가 다름
- 원인: 횟수형 푸터의 27pt 숫자로 셀 자연 높이가 유형별로 다른데(시간형 ~104 캡,
  횟수형 ~118), 아이패드 AdaptiveColumnsLayout(43be9c0)은 셀 고유 높이를 그대로
  배치해 차이가 노출 — 아이폰 LazyVGrid는 행 높이로 늘려 맞춰 가려졌음
- 수정 ①: 푸터에 횟수형 숫자 크기의 hidden 템플릿을 깔아 두 유형의 자연 높이 통일
  (magic number 없이 폰트에서 산출, compact 모드 포함, 접근성 숨김)
- 수정 ②: AdaptiveColumnsLayout.place가 LazyVGrid처럼 행 높이를 셀에 제안 —
  행 안 raggedness 제거. 측정(sizeThatFits) 불변이라 스크롤 진동 버그와 무관,
  고정 높이 목표 카드는 무영향
- 검증: 아이패드(3열 혼합/동일 유형 행)·아이폰 3열·compact 5열 스크린샷 균일 확인,
  Debug/Store 빌드 성공. 새 문자열 없음. CLAUDE.md §6.1 규칙 기재

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014CkLDi8Lr21vGqo4SjZaTp
This commit is contained in:
songyc macbook 2026-07-20 00:57:09 +09:00
parent e34ce8fa31
commit 1283c1f799
2 changed files with 15 additions and 4 deletions

View File

@ -175,7 +175,7 @@ xcrun xcstringstool sync Widgets/Localizable.xcstrings --stringsdata "${widget_f
- 상단: 노출 목표 진행 현황 카드(1개=단독, 2개+=스냅 페이징 가로 스크롤 + 페이지 점, iPad=그리드). 카드 스타일 설정: 다짐별 각각(perQuest, 접힘 시 3개+더보기) / 전체 합산(combined)
- "현재 진행 중" 영역: 측정 중 세션 나열 + 실시간 타이머 + 종료 버튼
- 행동 버튼 그리드: 꼬리표 색 그라데이션 배경 + 아이콘 + 이름 + 오늘 누적(시간형) 또는 오늘 횟수(횟수형, 숫자 전환 애니메이션). 측정 중이면 노란 테두리 + record 점. 탭 = 시작/종료 토글 또는 +1 (스프링 눌림 + 햅틱)
- 한 줄 개수: iPhone 2~6개 설정(5개 이상은 compact 셀), iPad는 화면 폭 자동 채움 — **iPad의 목표 카드·행동 그리드는 LazyVGrid가 아니라 비-lazy `AdaptiveColumnsLayout`**(MainView 내 커스텀 Layout, LazyVGrid(.adaptive)와 같은 열 계산). lazy 높이 추정이 높이 제각각인 목표 카드 + 1초 타이머 갱신과 결합해 맨 아래 스크롤 시 화면이 무한 진동(터치 불능)하는 실기기 버그의 수정 — iPhone(고정 열·페이징 높이 고정)은 LazyVGrid 유지. iPad 모음 그리드를 다시 lazy로 되돌리지 말 것
- 한 줄 개수: iPhone 2~6개 설정(5개 이상은 compact 셀), iPad는 화면 폭 자동 채움 — **iPad의 목표 카드·행동 그리드는 LazyVGrid가 아니라 비-lazy `AdaptiveColumnsLayout`**(MainView 내 커스텀 Layout, LazyVGrid(.adaptive)와 같은 열 계산). lazy 높이 추정이 높이 제각각인 목표 카드 + 1초 타이머 갱신과 결합해 맨 아래 스크롤 시 화면이 무한 진동(터치 불능)하는 실기기 버그의 수정 — iPhone(고정 열·페이징 높이 고정)은 LazyVGrid 유지. iPad 모음 그리드를 다시 lazy로 되돌리지 말 것. **행동 셀 높이 통일 규칙**: 시간형·횟수형 푸터 높이가 달라(횟수형 27pt 숫자) 셀 자연 높이가 달랐음 — 푸터에 숫자 크기의 hidden 템플릿(Text "0")을 깔아 두 유형의 자연 높이를 맞추고, AdaptiveColumnsLayout.place가 LazyVGrid처럼 행 높이를 제안해 행 안 셀도 균일(측정 패스는 불변이라 진동 버그와 무관, 고정 높이 목표 카드 무영향)
- 롱프레스 메뉴: 기록 확인(기록 탭 필터 이동) / 통계 보기 / 기록 직접 입력·수정 / 행동 설정 수정 / 삭제
- 배치 편집: 지글 애니메이션 + 드래그 재정렬 → `local.actionOrder` 저장 (CloudKit 모델에 쓰지 않음)
- "짧은 기록 무시"(minSessionSeconds): 설정보다 짧은 세션은 종료 시 삭제. 메모 창 옵션 켠 행동은 종료/+1 시 메모 시트(건너뛰기 가능)

View File

@ -921,11 +921,13 @@ struct AdaptiveColumnsLayout: Layout {
let rowEnd = min(index + layout.count, subviews.count)
var x = bounds.minX
for i in index..<rowEnd {
// , ( GridItem alignment: .top )
// LazyVGrid ( )
// ( Spacer , ).
// (sizeThatFits) .
subviews[i].place(
at: CGPoint(x: x, y: y),
anchor: .topLeading,
proposal: ProposedViewSize(width: layout.itemWidth, height: nil)
proposal: ProposedViewSize(width: layout.itemWidth, height: layout.heights[row])
)
x += layout.itemWidth + spacing
}
@ -973,7 +975,16 @@ struct ActionButtonCell: View {
.foregroundStyle(.white)
.lineLimit(compact ? 1 : 2)
.multilineTextAlignment(.leading)
footer
// · : ( )
// 릿
// AdaptiveColumnsLayout
ZStack(alignment: .bottomLeading) {
Text(verbatim: "0")
.font(.system(size: compact ? 18 : 27, weight: .heavy, design: .rounded))
.hidden()
.accessibilityHidden(true)
footer
}
}
.padding(compact ? 8 : 12)
.frame(minHeight: compact ? 68 : 104, alignment: .topLeading)