Polish the New Workout form: segmented When on top, pushed routine list
- When section moves to the top as a segmented control (3 or 4 segments depending on whether Now is offered) - Routine selection is a pushed list with each routine's symbol and color, checkmark on the current pick, select-and-pop - Goal "None" reserves the symbol slot so all goal labels align
This commit is contained in:
@@ -111,6 +111,13 @@ struct ScheduleAddEditView: View {
|
||||
/// The live routine currently selected; nil when the stored id no longer resolves.
|
||||
private var selectedRoutine: Routine? { routines.first { $0.id == routineID } }
|
||||
|
||||
/// The When choices this presentation offers — "Now" only when adding on today.
|
||||
/// Built as a list (rather than conditionally hiding a tag inside the Picker)
|
||||
/// so the segmented control renders a clean 3- or 4-segment strip.
|
||||
private var availableChoices: [WhenChoice] {
|
||||
offersNow ? WhenChoice.allCases : WhenChoice.allCases.filter { $0 != .now }
|
||||
}
|
||||
|
||||
private var canSave: Bool {
|
||||
guard selectedRoutine != nil else { return false }
|
||||
if when == .fixedDays { return !weekdays.isEmpty }
|
||||
@@ -120,11 +127,11 @@ struct ScheduleAddEditView: View {
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
Form {
|
||||
whenSection
|
||||
routineSection
|
||||
if when != .now {
|
||||
goalSection
|
||||
}
|
||||
whenSection
|
||||
}
|
||||
.navigationTitle(isEditing ? "Edit Workout" : "New Workout")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
@@ -148,9 +155,14 @@ struct ScheduleAddEditView: View {
|
||||
|
||||
private var routineSection: some View {
|
||||
Section {
|
||||
Picker("Routine", selection: $routineID) {
|
||||
ForEach(routines) { routine in
|
||||
Text(routine.name).tag(routine.id)
|
||||
NavigationLink {
|
||||
RoutinePickerList(routines: routines, selectedID: $routineID)
|
||||
} label: {
|
||||
HStack {
|
||||
Text("Routine")
|
||||
Spacer()
|
||||
Text(selectedRoutine?.name ?? "Choose…")
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
@@ -165,7 +177,14 @@ struct ScheduleAddEditView: View {
|
||||
private var goalSection: some View {
|
||||
Section {
|
||||
Picker("Goal", selection: $goal) {
|
||||
Text("None").tag(GoalKind?.none)
|
||||
// A hidden symbol placeholder keeps "None" aligned with the
|
||||
// symbol-bearing goal rows below it.
|
||||
Label {
|
||||
Text("None")
|
||||
} icon: {
|
||||
Image(systemName: "tag").hidden()
|
||||
}
|
||||
.tag(GoalKind?.none)
|
||||
ForEach(GoalKind.orderedCases()) { kind in
|
||||
Label(kind.displayName, systemImage: kind.systemImage)
|
||||
.foregroundStyle(Color.color(from: kind.colorName))
|
||||
@@ -183,12 +202,11 @@ struct ScheduleAddEditView: View {
|
||||
private var whenSection: some View {
|
||||
Section {
|
||||
Picker("When", selection: $when) {
|
||||
ForEach(WhenChoice.allCases) { choice in
|
||||
if choice != .now || offersNow {
|
||||
Text(choice.displayName).tag(choice)
|
||||
}
|
||||
ForEach(availableChoices) { choice in
|
||||
Text(choice.displayName).tag(choice)
|
||||
}
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
|
||||
switch when {
|
||||
case .now, .daily:
|
||||
@@ -260,3 +278,42 @@ struct ScheduleAddEditView: View {
|
||||
return (existing.map(\.order).max() ?? -1) + 1
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Routine picker
|
||||
|
||||
/// The pushed routine-selection list: each routine with its own symbol and color
|
||||
/// (the Today board's row treatment), a checkmark on the current selection.
|
||||
/// Tapping selects and pops back.
|
||||
private struct RoutinePickerList: View {
|
||||
let routines: [Routine]
|
||||
@Binding var selectedID: String
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
var body: some View {
|
||||
List(routines) { routine in
|
||||
Button {
|
||||
selectedID = routine.id
|
||||
dismiss()
|
||||
} label: {
|
||||
HStack(spacing: 12) {
|
||||
Image(systemName: routine.systemImage)
|
||||
.font(.title3)
|
||||
.foregroundStyle(Color.color(from: routine.color))
|
||||
.frame(width: 32)
|
||||
Text(routine.name)
|
||||
.foregroundStyle(.primary)
|
||||
Spacer()
|
||||
if routine.id == selectedID {
|
||||
Image(systemName: "checkmark")
|
||||
.fontWeight(.semibold)
|
||||
.foregroundStyle(Color.accentColor)
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
.navigationTitle("Routine")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user