add ValueKeyboard as input for exercise values

This commit is contained in:
Felix Förtsch
2024-09-27 17:17:32 +02:00
parent 4a42fc6c33
commit 41a82f081a
11 changed files with 308 additions and 124 deletions

View File

@@ -1,32 +0,0 @@
//
// ExerciseListItem.swift
// WorkoutsPlus
//
// Created by Felix Förtsch on 02.09.24.
//
import SwiftUI
struct ExerciseListItem: View {
var workout: Workout
@State var exercise: WorkoutItem
init(_ workout: Workout, _ exercise: WorkoutItem ) {
self.workout = workout
self.exercise = exercise
}
var body: some View {
Button(action: {
// workout.addExercise(from: exercise)
}) {
StepperListItem(itemName: exercise.name, itemValue: $exercise.reps)
}
}
}
#Preview {
List {
ExerciseListItem(Workout(name: "RR"), WorkoutItem(exercise: Exercise("Push-ups", .reps)))
}
}

View File

@@ -9,12 +9,7 @@ import SwiftUI
struct SetListItem: View {
var workout: Workout
@State var set: WorkoutItem
init(_ workout: Workout, _ set: WorkoutItem ) {
self.workout = workout
self.set = set
}
@Binding var set: WorkoutItem
var body: some View {
HStack {
@@ -44,7 +39,7 @@ struct SetListItem: View {
}
}
ForEach(set.set) { workoutItem in
ExerciseListItem(workout, workoutItem)
WorkoutListItem(workout, workoutItem)
.padding(.leading)
}
}
@@ -55,18 +50,18 @@ struct SetListItem: View {
}
#Preview {
let set = WorkoutItem(set: [
@Previewable @State var set = WorkoutItem(set: [
WorkoutItem(reps: 10, "Squat"),
WorkoutItem(reps: 10, "Squat"),
WorkoutItem(reps: 10, "Squat")])
List {
SetListItem(Workout(name: "RR"), set)
SetListItem(workout: Workout(name: "RR"), set: $set)
}
}
#Preview("Empty Database") {
let set = WorkoutItem(set: [])
@Previewable @State var set = WorkoutItem(set: [])
List {
SetListItem(Workout(name: "RR"), set)
SetListItem(workout: Workout(name: "RR"), set: $set)
}
}

View File

@@ -0,0 +1,175 @@
//
// ValuePickerKeyboard.swift
// WorkoutsPlus
//
// Created by Felix Förtsch on 24.09.24.
//
import SwiftUI
protocol ValueType {
associatedtype UnitType: CaseIterable & Hashable & CustomStringConvertible
var value: String { get set }
var unit: UnitType { get set }
}
enum ExerciseUnit: String, CaseIterable, CustomStringConvertible {
case reps = "reps"
case meter = "m"
case second = "s"
case speed = "m/s"
case pace = "s/m"
var description: String { rawValue }
}
struct ExerciseValue: ValueType {
var value: String = ""
var unit: ExerciseUnit = .reps
}
enum FoodUnit: String, CaseIterable, CustomStringConvertible {
case gram = "g"
case milliliter = "ml"
var description: String { rawValue }
}
struct FoodValue: ValueType {
var value: String = ""
var unit: FoodUnit = .gram
}
struct KeyboardButtonStyle: ButtonStyle {
var width: CGFloat = 100
var height: CGFloat = 50
var color: Color = Color(.systemGray6)
var font: Font = .system(size: 24, weight: .bold, design: .rounded)
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(width: width, height: height)
.background(color)
.cornerRadius(8)
.shadow(color: .gray, radius: 1, x: 0, y: 1)
.scaleEffect(configuration.isPressed ? 0.95 : 1.0)
.font(font)
}
}
struct ValueKeyboard<Value: ValueType>: View {
@Binding var isPresented: Bool
@Binding var value: Value
var body: some View {
VStack {
ZStack {
RoundedRectangle(cornerRadius: 8)
.fill(Color(.systemGray5))
.frame(height: 80)
HStack {
TextField("0", text: $value.value)
.font(.system(size: 32, weight: .bold, design: .rounded))
.padding()
Picker("Unit", selection: $value.unit) {
ForEach(Array(Value.UnitType.allCases), id: \.self) { unit in
Text(unit.description).tag(unit)
}
}
.pickerStyle(WheelPickerStyle())
.frame(width: 125, height: 125)
}
.padding()
.mask(RoundedRectangle(cornerRadius: 8).frame(height: 80))
}
.padding()
.frame(height: 100)
VStack(spacing: 20) {
HStack(spacing: 20) {
Button(action: { handleButtonTap("1") }) {
Text("1")
}
Button(action: { handleButtonTap("2") }) {
Text("2")
}
Button(action: { handleButtonTap("3") }) {
Text("3")
}
}
HStack(spacing: 20) {
Button(action: { handleButtonTap("4") }) {
Text("4")
}
Button(action: { handleButtonTap("5") }) {
Text("5")
}
Button(action: { handleButtonTap("6") }) {
Text("6")
}
}
HStack(spacing: 20) {
Button(action: { handleButtonTap("7") }) {
Text("7")
}
Button(action: { handleButtonTap("8") }) {
Text("8")
}
Button(action: { handleButtonTap("9") }) {
Text("9")
}
}
HStack(spacing: 20) {
Button(action: { handleButtonTap("") }) {
Text("")
}
Button(action: { handleButtonTap("0") }) {
Text("0")
}
Button(action: { handleButtonTap("") }) {
Text("")
}
.buttonStyle(KeyboardButtonStyle(color: .blue))
.foregroundStyle(.white)
}
}
.buttonStyle(KeyboardButtonStyle())
}
}
private func handleButtonTap(_ button: String) {
switch button {
case "":
if !value.value.isEmpty {
value.value.removeLast()
}
case "":
isPresented.toggle()
default:
value.value.append(button)
}
}
}
#Preview("ExerciseValue") {
@Previewable @State var exerciseValue: ExerciseValue = .init()
@Previewable @State var isPresented: Bool = true
Text(exerciseValue.value)
Text(exerciseValue.unit.rawValue)
ValueKeyboard(isPresented: $isPresented, value: $exerciseValue)
}
#Preview("FoodValue") {
@Previewable @State var foodValue: FoodValue = .init()
@Previewable @State var isPresented: Bool = true
Text(foodValue.value)
Text(foodValue.unit.rawValue)
ValueKeyboard(isPresented: $isPresented, value: $foodValue)
}