Thanks for your reply! Here's the complete code and detailed information:
Issue Description
I'm experiencing a strange behavior with Xcode Preview in my SwiftUI app:
On first Preview load: Button taps don't respond at all
Temporary workaround: Click any other file, then click back to ContentView - buttons work perfectly
Reproducibility: Happens 100% of the time after cleaning and restarting Preview
Environment
Xcode Version: Version 26.2
iOS Target: iOS 26.1
macOS Version: 26.1
Reproducibility: 100% consistent
Relevant Code
App Entry Point
import SwiftUI
import AVFoundation
@main
struct MyApp: App {
init() {
setupAudioSession()
}
private func setupAudioSession() {
do {
try AVAudioSession.sharedInstance().setCategory(
.playback,
mode: .default,
options: [.mixWithOthers]
)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("Failed to setup audio session: \(error)")
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}### ContentView - Simplified Version
import SwiftUI
struct ContentView: View {
@StateObject private var dataManager = DataManager.shared
@StateObject private var settingsManager = SettingsManager.shared
@StateObject private var sessionManager = SessionManager.shared
@State private var isSessionActive = false
@State private var selectedMode: Mode = .basic
@State private var showSettings = false
var body: some View {
GeometryReader { geometry in
ZStack {
Color.gray.opacity(0.1)
.ignoresSafeArea()
VStack(spacing: 30) {
// Header
if !isSessionActive {
Text("My App")
.font(.largeTitle)
.padding(.top, 60)
// Settings buttons
HStack {
SettingButton(title: "Mode", value: selectedMode.name) {
showSettings = true
}
}
.padding()
}
Spacer()
// Main content
Circle()
.fill(Color.blue.opacity(0.3))
.frame(width: 200, height: 200)
Text(isSessionActive ? "Active" : "Ready")
.font(.title2)
Spacer()
// 🔴 THIS BUTTON DOESN'T RESPOND ON FIRST PREVIEW LOAD
Button(action: {
print("Button tapped") // This doesn't print on first load
if isSessionActive {
endSession()
} else {
startSession()
}
}) {
Text(isSessionActive ? "Stop" : "Start")
.font(.system(size: 18))
.foregroundColor(.white)
.frame(width: 160, height: 44)
.background(Color.blue)
.cornerRadius(22)
}
.padding(.bottom, 60)
}
}
}
.edgesIgnoringSafeArea(.all)
.sheet(isPresented: $showSettings) {
SettingsView()
}
.onAppear {
initializeApp()
}
}
private func startSession() {
isSessionActive = true
sessionManager.start()
}
private func endSession() {
isSessionActive = false
sessionManager.stop()
}
private func initializeApp() {
dataManager.loadData()
settingsManager.loadSettings()
}
}
// Simple supporting types
enum Mode {
case basic, advanced
var name: String { self == .basic ? "Basic" : "Advanced" }
}
struct SettingButton: View {
let title: String
let value: String
let action: () -> Void
var body: some View {
Button(action: action) {
VStack {
Text(title)
.font(.caption)
Text(value)
.font(.subheadline)
}
.padding()
.background(Color.gray.opacity(0.2))
.cornerRadius(10)
}
}
}
struct SettingsView: View {
var body: some View {
Text("Settings")
}
}
#Preview {
ContentView()
}
Manager Singleton Pattern
class DataManager: ObservableObject {
static let shared = DataManager()
@Published var isReady = false
init() {
setupManager()
}
func setupManager() {
// Initialization code
}
func loadData() {
isReady = true
}
}
class SettingsManager: ObservableObject {
static let shared = SettingsManager()
@Published var settings: [String: Any] = [:]
func loadSettings() {
// Load settings
}
}
class SessionManager: ObservableObject {
static let shared = SessionManager()
@Published var isActive = false
func start() {
isActive = true
}
func stop() {
isActive = false
}
}## What I've Tried
All of the following did NOT fix the issue:
✅ Clean Build Folder & Derived Data
✅ Restart Xcode
✅ Remove .edgesIgnoringSafeArea(.all)
✅ Simplify Button action closure
✅ Reduce number of @StateObject dependencies
✅ Remove AVAudioSession setup from init
✅ Try .buttonStyle(PlainButtonStyle())
✅ Add explicit .contentShape(Rectangle()) to Button
✅ Test on different simulators
Suspected Factors
Multiple @StateObject singletons (3-5 managers)
AVAudioSession configured in App init
GeometryReader + ZStack layout
Preview state initialization timing issue
.sheet() modifiers attached to the view
Observations
✅ Real device/simulator: Works perfectly
❌ Xcode Preview (first load): Button completely unresponsive
✅ After switching files: Everything works normally
❌ After cleaning Preview: Problem comes back
Questions
Is this a known Xcode Preview bug?
Are there special considerations for multiple @StateObject in Previews?
Could AVAudioSession initialization block Preview interactivity?
Is there a way to force Preview to fully refresh its state?
Should singleton managers be initialized differently for Previews?
Any insights would be greatly appreciated! This is driving me crazy since the actual app works fine - it's purely a Preview issue affecting development workflow.
Additional Info: The workaround (switching files) is consistent but tedious. I've seen similar issues reported online but no clear solution yet.