Skip to content

Instantly share code, notes, and snippets.

@gfreezy
Forked from wangcheng/RecordingView.swift
Created October 29, 2025 06:26
Show Gist options
  • Save gfreezy/978fa16746c86b95adf8c74459fabb94 to your computer and use it in GitHub Desktop.
Save gfreezy/978fa16746c86b95adf8c74459fabb94 to your computer and use it in GitHub Desktop.
RecordingView.swift
//
// RecordingView.swift
// voicekeyboard
//
// Informational view shown when app is launched via voicekeyboard://record
// Pure UI component - business logic handled in voicekeyboardApp.handleRecognitionRequest
//
import SwiftUI
struct RecordingView: View {
@State private var animationOffset: CGFloat = -50
@State private var animationOpacity: Double = 0
private var bottomInset: CGFloat {
if let keyWindow = UIApplication.shared.keyWindow {
return keyWindow.safeAreaInsets.bottom
} else {
return 0
}
}
// Detect if device has home button (iPhone SE, older models)
private var hasHomeButton: Bool {
return bottomInset == 0
}
var body: some View {
ZStack {
VStack(spacing: 24) {
Image("AppIcon")
.resizable()
.scaledToFit()
.frame(width: 140, height: 140)
.clipShape(RoundedRectangle(cornerRadius: 44, style: .continuous))
.overlay(
RoundedRectangle(cornerRadius: 44, style: .continuous)
.stroke(Color.black.opacity(0.1), lineWidth: 0.5)
)
// Informational Text
Text("Due to system limitations, starting voice input requires opening the app")
.font(.headline)
.multilineTextAlignment(.center)
}
.padding(.horizontal, 30)
if hasHomeButton {
VStack {
// Animated tap indicator for top-left corner
HStack(spacing: 12) {
Image(systemName: "hand.tap.fill")
.font(.system(size: 32))
.foregroundColor(.accentColor)
.opacity(animationOpacity)
// Instructions for devices with home button (iPhone SE, etc.)
Text("Tap to return to the previous app.")
.font(.subheadline)
.foregroundColor(.secondary)
Spacer()
}
.padding(.horizontal, 12)
.onAppear { // Tap/pulse animation for home button devices
withAnimation(
.easeInOut(duration: 0.8)
.repeatForever(autoreverses: true)
) {
animationOpacity = 1
}
}
Spacer()
}
.id("a")
} else {
VStack {
Spacer()
// Instructions for devices with swipe gestures (iPhone X and newer)
Text("Swipe right to return to the previous app.")
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
// Animated swipe gesture indicator
HStack(spacing: 12) {
Image(systemName: "hand.tap.fill")
.font(.system(size: 32))
.foregroundColor(.accentColor)
.offset(x: animationOffset)
.opacity(animationOpacity)
Image(systemName: "arrow.right")
.font(.system(size: 16))
.foregroundColor(.accentColor)
.offset(x: animationOffset)
.opacity(animationOpacity)
}
.onAppear {
// Swipe animation for gesture-based devices
withAnimation(
.easeInOut(duration: 1.5)
.repeatForever(autoreverses: false)
) {
animationOffset = 50
animationOpacity = 1
}
withAnimation(
.easeInOut(duration: 0.75)
.repeatForever(autoreverses: true)
) {
animationOpacity = 0.3
}
}
}
.id("b")
}
}
}
}
#Preview {
NavigationView {
RecordingView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment