From 61cd78e080b395b50df0bdb742420139826a45b4 Mon Sep 17 00:00:00 2001 From: Yusuf Suleman Date: Sat, 4 Apr 2026 09:00:42 -0500 Subject: [PATCH] feat: speed controls in collapsed tab bar via safeAreaBar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uses .safeAreaBar(edge: .bottom) on the Reader content — the iOS 26 API that places content in the collapsed tab bar area, same position as the Now Playing mini bar. Speed controls [ - ] 1.50x [ + ] appear in the glass bar when auto-scrolling. Removed the floating speed pill overlay from ContentView. Co-Authored-By: Claude Opus 4.6 (1M context) --- ios/Platform/Platform/ContentView.swift | 45 +++---------------- .../Features/Reader/Views/ReaderTabView.swift | 26 +++++++++++ 2 files changed, 31 insertions(+), 40 deletions(-) diff --git a/ios/Platform/Platform/ContentView.swift b/ios/Platform/Platform/ContentView.swift index 3bc0712..ec77fa9 100644 --- a/ios/Platform/Platform/ContentView.swift +++ b/ios/Platform/Platform/ContentView.swift @@ -73,53 +73,18 @@ struct MainTabView: View { .tint(Color.accentWarm) .tabBarMinimizeBehavior(.onScrollDown) - // Bottom floating controls - VStack(spacing: 10) { - Spacer() - - // Speed pill (only when auto-scrolling on Reader) - if isAutoScrolling && selectedTab == 2 { - HStack(spacing: 12) { - Button { - scrollSpeed = max(0.25, scrollSpeed - 0.25) - } label: { - Image(systemName: "minus") - .font(.caption.weight(.bold)) - .foregroundStyle(Color.accentWarm) - .frame(width: 32, height: 32) - } - - Text(String(format: "%.2fx", scrollSpeed)) - .font(.system(size: 13, weight: .bold, design: .monospaced)) - .foregroundStyle(Color.textPrimary) - - Button { - scrollSpeed = min(3.0, scrollSpeed + 0.25) - } label: { - Image(systemName: "plus") - .font(.caption.weight(.bold)) - .foregroundStyle(Color.accentWarm) - .frame(width: 32, height: 32) - } - } - .padding(.horizontal, 16) - .padding(.vertical, 10) - .background(.regularMaterial, in: Capsule()) - .shadow(color: .black.opacity(0.15), radius: 12, y: 4) - .transition(.move(edge: .bottom).combined(with: .opacity)) - } - - // Feedback button (not on Reader) - if selectedTab != 2 { + // Feedback button (not on Reader) + if selectedTab != 2 { + VStack { + Spacer() HStack { FeedbackButton() .padding(.leading, 20) Spacer() } + .padding(.bottom, 70) } } - .padding(.bottom, 70) - .animation(.spring(duration: 0.3), value: isAutoScrolling) } .confettiCannon( trigger: $confettiTrigger, diff --git a/ios/Platform/Platform/Features/Reader/Views/ReaderTabView.swift b/ios/Platform/Platform/Features/Reader/Views/ReaderTabView.swift index 6cb2af2..5535a79 100644 --- a/ios/Platform/Platform/Features/Reader/Views/ReaderTabView.swift +++ b/ios/Platform/Platform/Features/Reader/Views/ReaderTabView.swift @@ -140,6 +140,32 @@ struct ReaderTabView: View { .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.canvas) .navigationBarHidden(true) + .safeAreaBar(edge: .bottom) { + if isAutoScrolling { + HStack(spacing: 16) { + Button { + scrollSpeed = max(0.25, scrollSpeed - 0.25) + } label: { + Image(systemName: "minus") + .font(.caption.weight(.bold)) + .foregroundStyle(Color.accentWarm) + } + + Text(String(format: "%.2fx", scrollSpeed)) + .font(.system(size: 13, weight: .bold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + + Button { + scrollSpeed = min(3.0, scrollSpeed + 0.25) + } label: { + Image(systemName: "plus") + .font(.caption.weight(.bold)) + .foregroundStyle(Color.accentWarm) + } + } + .padding(.horizontal, 20) + } + } .sheet(isPresented: $showFeedSheet) { AddFeedSheet(vm: vm) }