From f9b70dbb9d6b77e8f8b02b9bc35f7caf9827acd7 Mon Sep 17 00:00:00 2001 From: FuelBoard Contributor Date: Wed, 19 Aug 2026 07:09:54 +0100 Subject: [PATCH] anim: consistent bold crossfade in fuel-type picker --- FuelBoard/StationsView.swift | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/FuelBoard/StationsView.swift b/FuelBoard/StationsView.swift index aed1fa6..6e01e14 100644 --- a/FuelBoard/StationsView.swift +++ b/FuelBoard/StationsView.swift @@ -342,20 +342,26 @@ struct FuelTypeSegmentedPicker: View { var fuels: [FuelType] = FuelType.allCases var onSelect: (FuelType) -> Void = { _ in } + @Namespace private var selectionSlider + var body: some View { HStack(spacing: 3) { ForEach(fuels) { fuel in let isSelected = fuel == selection Button { - selection = fuel + withAnimation(.spring(response: 0.42, dampingFraction: 0.78)) { + selection = fuel + } onSelect(fuel) } label: { HStack(spacing: 5) { Image(systemName: "fuelpump.fill") .font(.caption2) .foregroundStyle(fuel.tintColor) + .scaleEffect(isSelected ? 1.08 : 0.94) Text(fuel.shortName) .font(.subheadline.weight(isSelected ? .semibold : .regular)) + .contentTransition(.opacity) } .foregroundStyle(isSelected ? Color.primary : Color.secondary) .frame(maxWidth: .infinity) @@ -364,14 +370,29 @@ struct FuelTypeSegmentedPicker: View { if isSelected { Capsule() .fill(Color(UIColor.systemBackground)) - .shadow(color: .black.opacity(0.08), radius: 1, y: 0.5) + .overlay { + Capsule() + .stroke(fuel.tintColor.opacity(0.28), lineWidth: 1) + } + .shadow(color: fuel.tintColor.opacity(0.16), radius: 6, y: 2) + .matchedGeometryEffect(id: "fuelSelectionSlider", in: selectionSlider) } } + .scaleEffect(isSelected ? 1.02 : 0.98) + .contentShape(Capsule()) } .buttonStyle(.plain) } } .padding(3) .background(Capsule().fill(Color(.secondarySystemBackground))) + .animation(.spring(response: 0.42, dampingFraction: 0.78), value: selection) } } + +#Preview("Fuel Picker") { + @Previewable @State var selectedFuel: FuelType = .e10 + FuelTypeSegmentedPicker(selection: $selectedFuel) + .padding() + .background(Color(.systemGroupedBackground)) +}