You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI添加列表项后背景色异常,视图层级出现叠加视图

问题解决:SwiftUI页面切换时背景色不一致的覆盖视图问题

问题根源

你遇到的“覆盖视图”其实是页面背景色不统一导致的视觉差异:主页面给List的容器设置了黑色背景,但进入SettingsView和Option1页面时,这些页面没有同步设置背景色,系统默认的浅色背景就会显现,和主页面的黑色形成对比,看起来像是额外的覆盖层。另外SwiftUI的List组件自带默认背景,也会加重这个问题。

修复步骤

  1. 全局统一背景色:给所有页面的根容器设置黑色背景,并确保覆盖安全区域
  2. 移除List默认背景:通过listStyle(.plain)和scrollContentBackground(.hidden)去掉List自带的背景样式
  3. 优化导航层级:改用新版NavigationStack替代旧的NavigationView,简化视图结构

修改后的完整代码

import SwiftUI

struct Goal: Identifiable {
    let id = UUID()
    let title: String
    let time: Date
    var isCompleted = false
}

class GoalsData: ObservableObject {
    @Published var goals: [Goal] = []
}

struct MainMenuView: View {
    @EnvironmentObject var goalsData: GoalsData
    
    let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "h:mm a"
        return formatter
    }()
    
    var body: some View {
        NavigationStack {
            VStack(spacing: 0) {
                // 顶部标题栏
                ZStack {
                    Color(.lightGray)
                        .edgesIgnoringSafeArea(.top)
                        .frame(height: 60)
                        .blendMode(.darken)
                    
                    HStack(alignment: .top) {
                        Text("TODAY")
                            .font(.largeTitle)
                            .fontWeight(.bold)
                            .padding(.leading)
                        
                        Spacer()
                        
                        NavigationLink(destination: SettingsView()) {
                            Image(systemName: "gearshape")
                                .foregroundColor(.blue)
                                .padding(.trailing)
                                .font(.title)
                        }
                    }
                }
                
                // 目标列表
                List {
                    ForEach(goalsData.goals) { goal in
                        Button(action: {
                            markCompleted(for: goal)
                        }) {
                            HStack {
                                Text(goal.title)
                                    .foregroundColor(.white)
                                Spacer()
                                Text(dateFormatter.string(from: goal.time))
                                    .foregroundColor(.white)
                                if goal.isCompleted {
                                    Image(systemName: "checkmark")
                                        .foregroundColor(.white)
                                }
                            }
                        }
                    }
                    .onDelete(perform: deleteGoal)
                }
                .listStyle(.plain)
                .scrollContentBackground(.hidden)
                .background(Color.black)
            }
            .background(Color.black.edgesIgnoringSafeArea(.all))
            .navigationBarTitleDisplayMode(.inline)
        }
    }
    
    func markCompleted(for goal: Goal) {
        if let index = goalsData.goals.firstIndex(where: { $0.id == goal.id }) {
            goalsData.goals[index].isCompleted.toggle()
        }
    }
    
    func deleteGoal(at offsets: IndexSet) {
        goalsData.goals.remove(atOffsets: offsets)
    }
}

class TimeData: ObservableObject {
    @Published var date: [String] = []
}

struct SettingsView: View {
    var body: some View {
        List {
            NavigationLink("Create goal", destination: Option1().environmentObject(TimeData()))
        }
        .listStyle(.plain)
        .scrollContentBackground(.hidden)
        .background(Color.black.edgesIgnoringSafeArea(.all))
        .foregroundColor(.white)
    }
}

struct Option1: View {
    @EnvironmentObject var goalsData: GoalsData
    @State var newGoal = ""
    @EnvironmentObject var timeData: TimeData
    @State var selectedDate = Date()
    
    let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "h:mm a"
        return formatter
    }()
    
    var body: some View {
        VStack {
            HStack {
                TextField("Enter new goal", text: $newGoal)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .foregroundColor(.white)
                
                DatePicker("Reminder Time:", selection: $selectedDate, displayedComponents: .hourAndMinute)
                    .datePickerStyle(CompactDatePickerStyle())
                    .foregroundColor(.white)
            }
            .padding()
            
            Button(action: {
                guard !newGoal.isEmpty else { return }
                let newGoal = Goal(title: newGoal, time: selectedDate)
                goalsData.goals.append(newGoal)
                self.newGoal = ""
            }) {
                Text("Set Goal")
                    .foregroundColor(.white)
            }
            .padding()
            
            Spacer()
        }
        .background(Color.black.edgesIgnoringSafeArea(.all))
    }
}

@main
struct MyApp: App {
    @StateObject var goalsData = GoalsData()
    var body: some Scene {
        WindowGroup {
            MainMenuView()
                .environmentObject(goalsData)
        }
    }
}

额外说明

  • 新版NavigationStack(iOS 16+)比旧的NavigationView层级更清晰,适配性更好
  • 统一设置文字为白色,避免黑色背景下文字不可见
  • 修正了TimeData中变量名的大小写问题,符合Swift命名规范

内容的提问来源于stack exchange,提问作者Huxley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:15:13