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

SwiftUI中Cannot find 'UserViewModel' in scope错误求助

解决SwiftUI中「Cannot find 'UserViewModel' in scope」错误

我正在开发SwiftUI应用,在HomeScreen.swift第11行实例化UserViewModel时遇到错误:Cannot find 'UserViewModel' in scope。已确认UserViewModel类已定义,且两个文件都导入了SwiftUI。

代码结构

UserViewModel.swift

import SwiftUI

class UserViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var errorMessage: String?
    
    func fetchUsers(completion: @escaping () -> Void = {}) {
        UserService.shared.fetchUsers { result in
            DispatchQueue.main.async {
                switch result {
                case .success(let users):
                    self.users = users.sorted { $0.id < $1.id }
                    completion()
                case .failure(let error):
                    self.errorMessage = error.localizedDescription
                }
            }
        }
    }
    
    func addUser(user: User) {
        if !users.contains(where: { $0.id == user.id }) {
            users.append(user)
        }
    }
}

HomeScreen.swift

import SwiftUI

struct HomeScreen: View {
    var currentUser: User
    
    @StateObject private var viewModel = UserViewModel()
    @State private var selectedUser: User?
    @State private var showAlert = false
    @State private var navigateToGameScreen = false
    
    var body: some View {
        NavigationView {
            VStack {
                HStack {
                    Spacer()
                    Text("Welcome, \(currentUser.firstName) \(currentUser.lastName)")
                        .padding()
                }
                
                VStack {
                    Text("Users")
                        .font(.largeTitle)
                        .fontWeight(.bold)
                        .padding(.bottom, 10)
                    
                    if let errorMessage = viewModel.errorMessage {
                        Text(errorMessage)
                            .foregroundColor(.red)
                            .padding()
                    } else {
                        List(viewModel.users) { user in
                            HStack {
                                Text("\(user.firstName) \(user.lastName)")
                                Spacer()
                                if currentUser.id != user.id {
                                    Button(action: {
                                        selectedUser = user
                                        showAlert = true
                                    }) {
                                        Text("Play")
                                            .foregroundColor(.blue)
                                    }
                                } else {
                                    Text("You")
                                        .foregroundColor(.gray)
                                }
                            }
                        }
                    }
                }
                .padding()
                .navigationTitle("")
                .navigationBarHidden(true)
            }
            .onAppear {
                viewModel.fetchUsers {
                    viewModel.addUser(user: currentUser)
                }
            }
            .alert(isPresented: $showAlert) {
                Alert(
                    title: Text("Play Game"),
                    message: Text("Do you want to play guess name with \(selectedUser?.username ?? "")?"),
                    primaryButton: .default(Text("Yay!"), action: {
                        navigateToGameScreen = true
                    }),
                    secondaryButton: .cancel(Text("Naah"))
                )
            }
            .background(
                NavigationLink(destination: GameScreen(opponentUsername: selectedUser?.username ?? "", loggedInUser: currentUser), isActive: $navigateToGameScreen) {
                    EmptyView()
                }
                .hidden()
            )
        }
        .navigationBarBackButtonHidden(true) // Hide back button
    }
}

struct HomeScreen_Previews: PreviewProvider {
    static var previews: some View {
        HomeScreen(currentUser: User(id: 1, firstName: "John", lastName: "Doe", age: 30, username: "johndoe", email: "john.doe@example.com"))
    }
}

已尝试的解决方法

  • 导入语句:确认两个文件均导入SwiftUI
  • 文件位置:确保两个文件属于同一Target,且在Xcode同一组中
  • 清理重建:尝试清理项目并重新构建
  • 重新导入:在UserViewModel.swift中添加import Foundation

可能的解决方案

1. 重新核对Target成员资格

选中UserViewModel.swift文件,打开右侧「File Inspector」(快捷键⌥⌘1),确认「Target Membership」下主应用Target的勾选状态,有时候会因为误操作取消勾选导致无法访问。

2. 检查类的访问修饰符

确保UserViewModel没有被添加private或fileprivate修饰符,默认的internal访问级别允许同一Target内的文件访问:

// 正确写法,无私有修饰符
class UserViewModel: ObservableObject {
    // ...
}

3. 重置Xcode索引与缓存

关闭Xcode,删除项目对应的DerivedData文件夹(路径为~/Library/Developer/Xcode/DerivedData/,可通过Xcode菜单File > Workspace Settings快速定位),重新打开项目并构建。

4. 确认文件名与拼写

检查UserViewModel.swift的文件名是否完全正确,Swift大小写敏感,确保文件名和类名的大小写、拼写完全匹配。

5. 排查命名冲突

确认项目中没有其他同名的UserViewModel类型,也没有其他文件中的同名类导致命名混淆。可以临时给类添加唯一后缀测试,比如改为AppUserViewModel,看是否能解决错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:14:54