- 첫 화면 우하단 ? 버튼 → 도움말(5그룹 13주제 — 기본 사용법·통계·앱 밖에서·애플워치·설정 기타) - String Catalog ko(원문)/en/ja 3타깃(iOS 98·워치 15·위젯 9키) 전수 번역, InfoPlist 표시 이름 포함 - 설정 → 언어(시스템/한국어/English/日本語) — AppleLanguages 오버라이드, 재실행 시 적용(하루 다님 방식) - 검증: Debug·Release·워치 빌드 그린, missing·stale 0, en/ja/ko 화면 QA 7장(도움말·설정·세팅·통계·워치) - DEBUG 인자 추가: -openHelp/-openSettings/-openTimerSettings/-resetConfig Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UPmp29DQHY6Ahfss5SRopT
134 lines
7.9 KiB
Swift
134 lines
7.9 KiB
Swift
//
|
|
// HelpView.swift
|
|
// Keging
|
|
//
|
|
// 도움말 — 앱의 모든 기능과 사용법. 첫 화면 물음표 버튼으로 진입.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct HelpView: View {
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
List {
|
|
Section {
|
|
helpRow(
|
|
symbol: "play.circle.fill",
|
|
title: Text("바로 시작하기"),
|
|
body: Text("첫 화면의 큰 시작 버튼을 누르면 저장된 세팅대로 바로 운동이 시작돼요. 화면의 원이 수축할 때 함께 조이고, 커질 때 힘을 풀면 돼요. 정해진 횟수를 모두 마치면 완료 화면이 뜨고 기록이 저장돼요.")
|
|
)
|
|
helpRow(
|
|
symbol: "slider.horizontal.3",
|
|
title: Text("운동 세팅 바꾸기"),
|
|
body: Text("오른쪽 위 슬라이더 버튼이 운동 세팅이에요. 수축 시간(1~60초), 이완 시간(1~60초), 반복 횟수(1~100회)를 정할 수 있어요. 예를 들어 수축 10초·이완 5초·20회로 설정하면, 수축과 이완을 20번 반복하는 한 세트가 약 5분이 돼요. 시작 버튼 아래의 요약 문구를 눌러도 이 화면이 열려요.")
|
|
)
|
|
helpRow(
|
|
symbol: "iphone.radiowaves.left.and.right",
|
|
title: Text("진동으로 구분하기"),
|
|
body: Text("수축이 시작될 때와 이완이 시작될 때 서로 다른 진동이 울려요. 그래서 화면을 보지 않아도 지금 조여야 할지 풀어야 할지 알 수 있어요. 진동 패턴은 운동 세팅에서 국면별로 고를 수 있고(한 번·두 번·세 번·심장 박동), '미리 느끼기' 버튼으로 실제 진동을 확인할 수 있어요. 진동은 실기기에서만 느껴져요.")
|
|
)
|
|
helpRow(
|
|
symbol: "stop.circle",
|
|
title: Text("중간에 중단하면"),
|
|
body: Text("운동 중 아래의 중단 버튼을 누르면 확인 후 세트가 끝나요. 중단한 세트는 아예 하지 않은 것으로 처리돼서 기록과 통계에 남지 않아요. 끝까지 마친 세트만 기록돼요.")
|
|
)
|
|
} header: {
|
|
Text("기본 사용법")
|
|
}
|
|
|
|
Section {
|
|
helpRow(
|
|
symbol: "chart.xyaxis.line",
|
|
title: Text("통계 열기"),
|
|
body: Text("첫 화면을 아래로 쓸어내리거나 위쪽 가운데의 손잡이를 누르면 통계 화면이 열려요. 닫을 때는 위로 쓸어올리거나 X 버튼을 누르면 돼요.")
|
|
)
|
|
helpRow(
|
|
symbol: "calendar",
|
|
title: Text("하루 · 주간 · 월간"),
|
|
body: Text("하루 탭에서는 오늘 몇 시에 몇 회를 했는지 목록과 시간대별 꺾은선 그래프로 보여줘요. 주간·월간 탭에서는 일별 횟수를 꺾은선 그래프와 합계(세트·횟수)로 보여줘요. 주는 월요일에 시작해요.")
|
|
)
|
|
helpRow(
|
|
symbol: "arrow.left.arrow.right",
|
|
title: Text("이번 주 ↔ 지난 7일 전환"),
|
|
body: Text("주간·월간 화면 위의 스위치로 두 가지 방식을 오갈 수 있어요. '이번 주 / 이번 달'은 달력 기준(월요일~일요일, 1일~말일)이고, '지난 7일 / 지난 30일'은 오늘을 기준으로 거슬러 세는 방식이에요.")
|
|
)
|
|
} header: {
|
|
Text("통계")
|
|
}
|
|
|
|
Section {
|
|
helpRow(
|
|
symbol: "bolt.horizontal.circle",
|
|
title: Text("다이나믹 아일랜드"),
|
|
body: Text("운동 중에 앱을 나가면 다이나믹 아일랜드에 현재 몇 번째인지와 수축·이완 상태가 떠요. 길게 누르면 남은 시간과 진행 바가 보이는 큰 화면이 열려요. 진동도 계속 울리니까 다른 앱을 쓰면서도 운동을 이어갈 수 있어요.")
|
|
)
|
|
helpRow(
|
|
symbol: "square.and.arrow.up",
|
|
title: Text("단축어와 시리"),
|
|
body: Text("단축어 앱에서 '케겔 운동 시작' 동작을 추가할 수 있어요. 실행하면 케깅이 열리면서 저장된 세팅대로 바로 시작돼요. 홈 화면 아이콘·잠금화면 위젯·뒷면 탭 등 단축어를 부를 수 있는 곳이라면 어디서든 쓸 수 있어요.")
|
|
)
|
|
} header: {
|
|
Text("앱 밖에서")
|
|
}
|
|
|
|
Section {
|
|
helpRow(
|
|
symbol: "applewatch",
|
|
title: Text("애플워치에서 운동하기"),
|
|
body: Text("워치 앱을 열면 시작 버튼 하나만 있어요. 누르면 바로 시작되고, 화면에 수축·이완 상태와 남은 시간, 몇 번째인지가 한눈에 보여요. 워치에서 실행하면 진동은 워치에서만 울려요. 중단 버튼을 누르면 그 세트는 기록되지 않아요.")
|
|
)
|
|
helpRow(
|
|
symbol: "arrow.triangle.2.circlepath",
|
|
title: Text("워치와 아이폰 동기화"),
|
|
body: Text("운동 세팅은 아이폰에서만 바꿀 수 있고, 바꾸면 워치에 자동으로 전달돼요. 워치에서 끝까지 마친 세트는 아이폰으로 넘어와 통계에 합쳐져요. 워치가 아이폰과 떨어져 있어도 기록은 쌓였다가 연결되면 자동으로 전송돼요.")
|
|
)
|
|
} header: {
|
|
Text("애플워치")
|
|
}
|
|
|
|
Section {
|
|
helpRow(
|
|
symbol: "paintbrush",
|
|
title: Text("테마와 언어"),
|
|
body: Text("왼쪽 위 톱니바퀴 버튼이 설정이에요. 화면 모드(시스템·라이트·다크)와 언어(시스템·한국어·English·日本語)를 고를 수 있어요. 언어는 앱을 완전히 종료했다가 다시 실행하면 적용돼요. 워치는 워치의 시스템 언어를 따라요.")
|
|
)
|
|
helpRow(
|
|
symbol: "lock.shield",
|
|
title: Text("데이터와 개인정보"),
|
|
body: Text("케깅은 광고와 결제가 없는 완전 무료 앱이에요. 모든 기록은 이 기기(그리고 워치)에만 저장되고, 외부 서버로 전송되지 않아요.")
|
|
)
|
|
} header: {
|
|
Text("설정·기타")
|
|
}
|
|
}
|
|
.navigationTitle("도움말")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .confirmationAction) {
|
|
Button("완료") { dismiss() }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func helpRow(symbol: String, title: Text, body: Text) -> some View {
|
|
VStack(alignment: .leading, spacing: 6) {
|
|
HStack(spacing: 8) {
|
|
Image(systemName: symbol)
|
|
.font(.body)
|
|
.foregroundStyle(AppTheme.green)
|
|
.frame(width: 24)
|
|
title
|
|
.font(.headline)
|
|
}
|
|
body
|
|
.font(.subheadline)
|
|
.foregroundStyle(.secondary)
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
}
|
|
.padding(.vertical, 4)
|
|
}
|
|
}
|