Libelle: Blase wandert zur höheren Seite, einheitlich auf allen Anzeigen

Die drei Libellen widersprachen sich: Die Live Activity liess die Blase bei
positivem Pitch nach unten wandern – mit dem Kommentar "wie bei der echten
Wasserwaage in der App" –, waehrend iPhone und Uhr genau das Gegenteil taten.
Gemeint war immer eine Draufsicht mit Fahrtrichtung oben, in der die Blase zur
hoeheren Seite ausschlaegt: Steht das Heck hoeher, gehoert sie nach hinten,
also nach unten. iPhone und Uhr ziehen jetzt nach.

Die Android-Fassung bleibt vorerst bei der alten Richtung.

Dazu `shortInstructions`: dieselbe Aussage wie `instruction`, aber in kurzen
Zeilen statt einem Satz. Auf schmalen Anzeigen passt "Heck steht hoeher, links
steht hoeher" in keine lesbare Zeile. Beide stehen nebeneinander, damit die
Vorzeichen nicht auseinanderlaufen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
fototeddy
2026-09-10 18:35:14 +02:00
co-authored by Claude Opus 5
parent 8401f62d91
commit b1ffbe324a
3 changed files with 28 additions and 6 deletions
+19
View File
@@ -65,6 +65,25 @@ struct LevelState: Equatable, Codable, Sendable {
return parts.joined(separator: ", ") return parts.joined(separator: ", ")
} }
/// Dasselbe wie ``instruction``, aber in kurzen Zeilen statt einem Satz
/// für schmale Anzeigen wie das CarPlay-Display, wo "Heck steht höher,
/// rechts steht höher" nicht in eine lesbare Zeile passt.
///
/// Die Vorzeichen müssen zu ``instruction`` passen; beide stehen deshalb
/// nebeneinander.
var shortInstructions: [String] {
guard let pitch, let roll else { return [] }
if isLevel { return ["Steht eben"] }
var parts: [String] = []
if abs(pitch) > Self.levelTolerance {
parts.append(pitch > 0 ? "Heck höher" : "Front höher")
}
if abs(roll) > Self.levelTolerance {
parts.append(roll > 0 ? "Rechts höher" : "Links höher")
}
return parts
}
func snapshot(deviceID: UUID, rssi: Int?) -> DeviceSnapshot { func snapshot(deviceID: UUID, rssi: Int?) -> DeviceSnapshot {
var snapshot = DeviceSnapshot(deviceID: deviceID, timestamp: Date(), rssi: rssi) var snapshot = DeviceSnapshot(deviceID: deviceID, timestamp: Date(), rssi: rssi)
snapshot.metrics = [ snapshot.metrics = [
+5 -3
View File
@@ -75,9 +75,11 @@ struct LevelBubble: View {
Circle() Circle()
.fill(bubbleColor) .fill(bubbleColor)
.frame(width: bubble, height: bubble) .frame(width: bubble, height: bubble)
// Positiver Pitch heisst: das Heck steht höher, die Blase // Draufsicht mit Fahrtrichtung oben: Positiver Pitch heisst,
// wandert also nach oben in der Ansicht nach hinten. // das Heck steht höher die Blase wandert nach hinten, also
.offset(x: offsetX, y: -offsetY) // nach unten. Wie bei einer echten Wasserwaage, die zur
// höheren Seite ausschlägt.
.offset(x: offsetX, y: offsetY)
.animation(.spring(duration: 0.35), value: offsetX) .animation(.spring(duration: 0.35), value: offsetX)
.animation(.spring(duration: 0.35), value: offsetY) .animation(.spring(duration: 0.35), value: offsetY)
.opacity(pitch == nil && roll == nil ? 0.25 : 1) .opacity(pitch == nil && roll == nil ? 0.25 : 1)
+4 -3
View File
@@ -30,10 +30,11 @@ struct WatchBubble: View {
Circle() Circle()
.fill(color) .fill(color)
.frame(width: bubble, height: bubble) .frame(width: bubble, height: bubble)
// Positiver Pitch heisst: das Heck steht höher, die Blase // Draufsicht mit Fahrtrichtung oben: Positiver Pitch heisst,
// wandert nach oben in der Ansicht also nach hinten. // das Heck steht höher die Blase wandert nach hinten, also
// nach unten.
.offset(x: clamped(roll) / range * travel, .offset(x: clamped(roll) / range * travel,
y: -clamped(pitch) / range * travel) y: clamped(pitch) / range * travel)
.animation(.spring(duration: 0.3), value: pitch) .animation(.spring(duration: 0.3), value: pitch)
.animation(.spring(duration: 0.3), value: roll) .animation(.spring(duration: 0.3), value: roll)
.opacity(pitch == nil && roll == nil ? 0.25 : 1) .opacity(pitch == nil && roll == nil ? 0.25 : 1)