Skip to content

Commit

Permalink
Merge pull request #17 from jhrcook/improved-spinner
Browse files Browse the repository at this point in the history
Improved spinner
  • Loading branch information
jhrcook authored Jan 17, 2021
2 parents 89d82d7 + 4b39a3a commit f205c18
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,12 @@ enum UserDefaultsKeys: String {
case exerciseIntensity
case activeBodyParts
case exerciseOptions
case crownVelocityMultiplier
}

extension UserDefaults {
static func readCrownVelocityMultiplier() -> Double {
let m = standard.double(forKey: UserDefaultsKeys.crownVelocityMultiplier.rawValue)
return m > 0.0 ? m : 1.0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import SwiftUI

extension ExercisePicker {
func crownRotationDidChange(crownValue: Double) {
crownVelocity.update(newValue: crownValue)
func crownRotationDidChange(crownValue _: Double) {
crownVelocity.update(newValue: wheelRotation)
readSelectedWorkout()
}

Expand All @@ -24,7 +24,7 @@ extension ExercisePicker {
func readSelectedWorkout() {
let pointerAngle = 180.0
let sliceAngle = 360.0 / Double(numExercises)
let pointingAtAngle = (0.5 * sliceAngle) + (pointerAngle - spinDirection * crownRotation)
let pointingAtAngle = (0.5 * sliceAngle) + (pointerAngle - spinDirection * wheelRotation)
.truncatingRemainder(dividingBy: 360.0)
var pointingSlice = (pointingAtAngle / sliceAngle).rounded(.down)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ struct ExercisePicker: View {
@ObservedObject var workoutManager: WorkoutManager
@ObservedObject var exerciseOptions: ExerciseOptions
@State internal var crownRotation = 0.0
var wheelRotation: Double {
crownRotation * crownVelocityMultiplier
}

var numExercises: Int {
return exerciseOptions.exercisesBlacklistFiltered.count
}

var crownVelocity = CrownVelocityCalculator(velocityThreshold: 50, memory: 20)
var crownVelocityMultiplier = UserDefaults.readCrownVelocityMultiplier()

@Binding internal var exerciseSelected: Bool
@State internal var selectedExerciseIndex: Int = 0
Expand Down Expand Up @@ -58,7 +62,7 @@ struct ExercisePicker: View {
}
}
.modifier(SpinnerRotationModifier(
rotation: .degrees(self.spinDirection * self.crownRotation),
rotation: .degrees(self.spinDirection * self.wheelRotation),
onFinishedRotationAnimation: self.rotationEffectDidFinish
))
.animation(.default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,30 @@ struct SectionHeader: View {
}
}

struct SpinningImageSectionHeader: View {
let imageName: String
let text: String

@State private var angle: Angle = .degrees(0.0)

var body: some View {
HStack {
Image(systemName: imageName)
.rotationEffect(angle)
.animation(Animation.linear(duration: 2.0).repeatForever(autoreverses: false))
.onAppear {
self.angle = .degrees(360)
}
Text(text)
}
}
}

struct SectionHeader_Previews: PreviewProvider {
static var previews: some View {
SectionHeader(imageName: "mustache", text: "Text")
Group {
SectionHeader(imageName: "mustache", text: "Text")
SpinningImageSectionHeader(imageName: "mustache", text: "Text")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,24 @@ struct Settings: View {
}

@State private var confirmResetExerciseOptions = false
@Environment(\.presentationMode) var presentationMode

@State private var crownVelocityMultiplier = UserDefaults.readCrownVelocityMultiplier()

private var crownVelocityMultiplierValues: [Double] = {
var a: [Double] = []
for x in 1 ... 10 {
a.append(Double(x) * 0.5)
}
return a
}()

@Environment(\.presentationMode) var presentationMode
let logger = Logger.settingsLogger

init(exerciseOptions: ExerciseOptions) {
self.exerciseOptions = exerciseOptions
}

var body: some View {
Form {
Section(header: SectionHeader(imageName: "figure.wave", text: "Preferences")) {
Expand Down Expand Up @@ -60,11 +74,25 @@ struct Settings: View {
}
}

Section(header: SpinningImageSectionHeader(imageName: "hexagon", text: "Spinning Wheel")) {
Picker(selection: $crownVelocityMultiplier, label: Text("Spin speed"), content: {
ForEach(crownVelocityMultiplierValues, id: \.self) { x in
Text("\(x, specifier: "%.1f")")
}
})
.pickerStyle(WheelPickerStyle())
}

Section(header: SectionHeader(imageName: "info.circle", text: "About")) {
HStack {
Text("Dev")
Spacer()
Text("Josh Cook")
}
HStack {
Text("Version")
Spacer()
Text("1.2.0")
Text("1.2.2")
}
}
}
Expand Down Expand Up @@ -97,9 +125,12 @@ struct Settings: View {
extension Settings {
func saveUserDefualts() {
let intensity = ExerciseIntensity.allCases[selectedExerciseIntensity]
logger.log("Saving preferences to UserDefaults (intensity: \(intensity.rawValue, privacy: .public))")
logger.log("Saving preferences to UserDefaults (intensity: \(intensity.rawValue, privacy: .public); crown velocity: \(crownVelocityMultiplier, format: .fixed(precision: 1)))")
UserDefaults.standard.set(intensity.rawValue,
forKey: UserDefaultsKeys.exerciseIntensity.rawValue)

UserDefaults.standard.set(crownVelocityMultiplier,
forKey: UserDefaultsKeys.crownVelocityMultiplier.rawValue)
}

static func getSavedExerciseIntensity() -> Int {
Expand Down
12 changes: 6 additions & 6 deletions Workout Spinner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = "com.joshuacook.Workout-Spinner.watchkitapp.watchkitextension";
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
Expand All @@ -742,7 +742,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = "com.joshuacook.Workout-Spinner.watchkitapp.watchkitextension";
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
Expand All @@ -763,7 +763,7 @@
DEVELOPMENT_TEAM = CRMHYJ9F9F;
IBSC_MODULE = Workout_Spinner_WatchKit_Extension;
INFOPLIST_FILE = "Workout Spinner WatchKit App/Info.plist";
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = "com.joshuacook.Workout-Spinner.watchkitapp";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
Expand All @@ -784,7 +784,7 @@
DEVELOPMENT_TEAM = CRMHYJ9F9F;
IBSC_MODULE = Workout_Spinner_WatchKit_Extension;
INFOPLIST_FILE = "Workout Spinner WatchKit App/Info.plist";
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = "com.joshuacook.Workout-Spinner.watchkitapp";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
Expand All @@ -801,7 +801,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 0;
DEVELOPMENT_TEAM = CRMHYJ9F9F;
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = "com.joshuacook.Workout-Spinner";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -814,7 +814,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 0;
DEVELOPMENT_TEAM = CRMHYJ9F9F;
MARKETING_VERSION = 1.2.1;
MARKETING_VERSION = 1.2.2;
PRODUCT_BUNDLE_IDENTIFIER = "com.joshuacook.Workout-Spinner";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,18 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "32">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Workout Spinner WatchKit App">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand All @@ -73,16 +75,27 @@
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "32">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Workout Spinner WatchKit App">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,18 @@
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "8"
notificationPayloadFile = "Workout Spinner WatchKit Extension/PushNotificationPayload.apns">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Workout Spinner WatchKit App">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand All @@ -75,16 +77,27 @@
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "8"
notificationPayloadFile = "Workout Spinner WatchKit Extension/PushNotificationPayload.apns">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Workout Spinner WatchKit App">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,33 +55,46 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
notificationPayloadFile = "Workout Spinner WatchKit Extension/PushNotificationPayload.apns">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Workout Spinner WatchKit App">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Workout Spinner WatchKit App">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84E3727E24FD0A5800AFB355"
BuildableName = "Workout Spinner WatchKit App.app"
BlueprintName = "Workout Spinner WatchKit App"
ReferencedContainer = "container:Workout Spinner.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down

0 comments on commit f205c18

Please sign in to comment.