Wetterkachel füllt die Kachel und ist lesbar
Alles stand im oberen Drittel, die untere Hälfte war leer — und die Stundenwerte in acht Punkten, die man auf Armlänge nicht entziffert. Der Aufbau folgt jetzt der Reihenfolge, in der man liest: erst was jetzt ist — großes Symbol, große Temperatur, Höchst- und Tiefstwert daneben, darunter der Ort und die gefühlte Temperatur —, dann getrennt durch eine Linie, was noch kommt. Vier Stunden statt fünf: bei 180 Punkten Breite bleiben so gut vierzig je Spalte, und die Zahlen lassen sich in einer Größe setzen, die man auch liest. Die fünfte Stunde war der Grund, warum alles zusammengedrückt war. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"weather.feelsLike %@": {
|
||||||
|
"localizations": {
|
||||||
|
"de": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "gefühlt %@"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"en": {
|
||||||
|
"stringUnit": {
|
||||||
|
"state": "translated",
|
||||||
|
"value": "feels like %@"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"widget.weather.asOf": {
|
"widget.weather.asOf": {
|
||||||
"comment": "%@ ist die Uhrzeit des Messwerts",
|
"comment": "%@ ist die Uhrzeit des Messwerts",
|
||||||
"localizations": {
|
"localizations": {
|
||||||
|
|||||||
@@ -210,52 +210,72 @@ private struct WideWeather: View {
|
|||||||
let isStale: Bool
|
let isStale: Bool
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 6) {
|
// Der Aufbau folgt der Reihenfolge, in der man liest: erst was jetzt
|
||||||
HStack(alignment: .top, spacing: 8) {
|
// ist, dann was noch kommt. Vorher stand alles im oberen Drittel und
|
||||||
|
// die untere Hälfte war leer — bei Schriftgrößen von acht Punkten, die
|
||||||
|
// man auf Armlänge nicht entziffert.
|
||||||
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
|
HStack(alignment: .center, spacing: 10) {
|
||||||
Image(systemName: snapshot.condition.symbolName(isDaylight: snapshot.isDaylight))
|
Image(systemName: snapshot.condition.symbolName(isDaylight: snapshot.isDaylight))
|
||||||
.font(.system(size: 22))
|
.font(.system(size: 34))
|
||||||
.symbolRenderingMode(.hierarchical)
|
.symbolRenderingMode(.hierarchical)
|
||||||
.foregroundStyle(Onyx.Color.textPrimary)
|
.foregroundStyle(Onyx.Color.textPrimary)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 1) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
Text(snapshot.temperature.onyxFormatted)
|
Text(snapshot.temperature.onyxFormatted)
|
||||||
.font(Onyx.Font.metric)
|
.font(.system(size: 30, weight: .medium))
|
||||||
|
.monospacedDigit()
|
||||||
.foregroundStyle(Onyx.Color.textPrimary)
|
.foregroundStyle(Onyx.Color.textPrimary)
|
||||||
Text(snapshot.placeName)
|
if let high = snapshot.high, let low = snapshot.low {
|
||||||
.font(.system(size: 10))
|
Text("↑ \(high.onyxFormatted) ↓ \(low.onyxFormatted)")
|
||||||
.foregroundStyle(Onyx.Color.textSecondary)
|
.font(Onyx.Font.metricSmall)
|
||||||
.lineLimit(1)
|
.monospacedDigit()
|
||||||
|
.foregroundStyle(Onyx.Color.textTertiary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Spacer(minLength: 0)
|
Spacer(minLength: 0)
|
||||||
|
|
||||||
if let high = snapshot.high, let low = snapshot.low {
|
|
||||||
VStack(alignment: .trailing, spacing: 1) {
|
|
||||||
Text("↑ \(high.onyxFormatted)")
|
|
||||||
Text("↓ \(low.onyxFormatted)")
|
|
||||||
}
|
|
||||||
.font(Onyx.Font.metricSmall)
|
|
||||||
.foregroundStyle(Onyx.Color.textTertiary)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text(snapshot.placeName)
|
||||||
|
.font(Onyx.Font.caption)
|
||||||
|
.foregroundStyle(Onyx.Color.textSecondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
.padding(.top, 2)
|
||||||
|
|
||||||
|
if snapshot.apparentTemperature != snapshot.temperature {
|
||||||
|
Text("weather.feelsLike \(snapshot.apparentTemperature.onyxFormatted)",
|
||||||
|
bundle: .module)
|
||||||
|
.font(Onyx.Font.metricSmall)
|
||||||
|
.foregroundStyle(Onyx.Color.textTertiary)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(minLength: 6)
|
||||||
|
|
||||||
if !snapshot.hourly.isEmpty {
|
if !snapshot.hourly.isEmpty {
|
||||||
|
Divider().overlay(Onyx.Color.hairline)
|
||||||
|
|
||||||
|
// Vier statt fünf Stunden: bei 180 Punkten Breite bleiben so
|
||||||
|
// gut vierzig je Spalte, und die Zahlen lassen sich in einer
|
||||||
|
// lesbaren Größe setzen.
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
ForEach(snapshot.hourly.prefix(5)) { point in
|
ForEach(snapshot.hourly.prefix(4)) { point in
|
||||||
VStack(spacing: 2) {
|
VStack(spacing: 3) {
|
||||||
Text(point.date.formatted(.dateTime.hour()))
|
Text(point.date.formatted(.dateTime.hour()))
|
||||||
.font(.system(size: 8))
|
.font(Onyx.Font.metricSmall)
|
||||||
.foregroundStyle(Onyx.Color.textTertiary)
|
.foregroundStyle(Onyx.Color.textTertiary)
|
||||||
Image(systemName: point.condition.symbolName(isDaylight: true))
|
Image(systemName: point.condition.symbolName(isDaylight: true))
|
||||||
.font(.system(size: 9))
|
.font(.system(size: 13))
|
||||||
|
.symbolRenderingMode(.hierarchical)
|
||||||
.foregroundStyle(Onyx.Color.textSecondary)
|
.foregroundStyle(Onyx.Color.textSecondary)
|
||||||
Text(point.temperature.onyxFormatted)
|
Text(point.temperature.onyxFormatted)
|
||||||
.font(.system(size: 9))
|
.font(Onyx.Font.caption)
|
||||||
.monospacedDigit()
|
.monospacedDigit()
|
||||||
.foregroundStyle(Onyx.Color.textSecondary)
|
.foregroundStyle(Onyx.Color.textPrimary)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.padding(.vertical, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(minLength: 0)
|
Spacer(minLength: 0)
|
||||||
@@ -263,17 +283,17 @@ private struct WideWeather: View {
|
|||||||
HStack(spacing: 4) {
|
HStack(spacing: 4) {
|
||||||
if isStale {
|
if isStale {
|
||||||
Image(systemName: "exclamationmark.triangle.fill")
|
Image(systemName: "exclamationmark.triangle.fill")
|
||||||
.font(.system(size: 8))
|
.font(.system(size: 9))
|
||||||
.foregroundStyle(Onyx.Color.warning)
|
.foregroundStyle(Onyx.Color.warning)
|
||||||
}
|
}
|
||||||
Text(stampText)
|
Text(stampText)
|
||||||
.font(.system(size: 8))
|
.font(Onyx.Font.metricSmall)
|
||||||
.foregroundStyle(Onyx.Color.textTertiary)
|
.foregroundStyle(Onyx.Color.textTertiary)
|
||||||
Spacer(minLength: 0)
|
Spacer(minLength: 0)
|
||||||
if let attribution = snapshot.attribution {
|
if let attribution = snapshot.attribution {
|
||||||
// Pflichtangabe, klickbar auf Apples Rechtshinweise.
|
// Pflichtangabe, klickbar auf Apples Rechtshinweise.
|
||||||
Link(attribution.name, destination: attribution.legalPageURL)
|
Link(attribution.name, destination: attribution.legalPageURL)
|
||||||
.font(.system(size: 8))
|
.font(Onyx.Font.metricSmall)
|
||||||
.foregroundStyle(Onyx.Color.textTertiary)
|
.foregroundStyle(Onyx.Color.textTertiary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user