I am trying to call ViewModel method in the view but getting error as Thread 1: Fatal error: No ObservableObject of type AuthViewModel found. A View.environmentObject(_:) for AuthViewModel may be missing as an ancestor of this view. I don't have any idea why it is happening.
AuthViewModel
import SwiftUI
class AuthViewModel: ObservableObject {
func login() {
print("Hello")
}
}
My View File
//
// RegistrationView.swift
// TwitterSwiftUI
//
// Created by developer on 11/06/21.
//
import SwiftUI
struct RegistrationView: View {
@State var text = ""
@State var fullName = ""
@State var userName = ""
@State var password = ""
@State var isImagePickerDisplay = false
@State var selectedImage:UIImage?
@Environment(\.presentationMode) var mode: Binding<PresentationMode>
@EnvironmentObject var viewModel: AuthViewModel
var body: some View {
ZStack {
Color(#colorLiteral(red: 0.2203325033, green: 0.6315936446, blue: 0.955042541, alpha: 1))
.ignoresSafeArea()
VStack {
Button(action: {
isImagePickerDisplay = true
}, label: {
if selectedImage != nil {
Image(uiImage: selectedImage!)
.resizable()
.scaledToFit()
.frame(width: 140, height: 140)
.padding(.top, 0)
} else {
Image("plus_photo")
.resizable()
.renderingMode(/*@START_MENU_TOKEN@*/.template/*@END_MENU_TOKEN@*/)
.foregroundColor(.white)
.scaledToFit()
.frame(width: 140, height: 140)
.padding(.top, 0)
}
})
VStack {
CustomTextField(text: $fullName, placeholder: Text("Full name"), icon: Image(systemName: "person"))
.foregroundColor(.white)
.padding()
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
CustomTextField(text: $fullName, placeholder: Text("Email"), icon: Image(systemName: "envelope"))
.foregroundColor(.white)
.padding()
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
CustomTextField(text: $userName, placeholder: Text("Username"), icon: Image(systemName: "person"))
.foregroundColor(.white)
.padding()
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
CustomSecureField(password: $password)
.foregroundColor(.white)
.padding()
.background(Color(.init(white: 1, alpha: 0.15)))
.cornerRadius(10)
Spacer()
.frame(height: 30)
GeometryReader { geometry in
Button(action: {
//viewModel.registerUser(email: "userName", password: "password", userName: "userName", fullName: "fullName", profileImage: selectedImage)
viewModel.login()
}, label: {
Text("Sign up")
})
.frame(width: (geometry.size.width*1), height: 50)
.background(Color.white)
.clipShape(Capsule())
.padding(.vertical)
}
}.padding()
Spacer()
HStack {
Text("Already have account? Login in")
.foregroundColor(.white)
}.onTapGesture {
mode.wrappedValue.dismiss()
}.padding(.bottom, 28)
}
}.sheet(isPresented: self.$isImagePickerDisplay) {
ImagePickerViewHelper(selectedImage: self.$selectedImage, sourceType: .photoLibrary)
}
}
}
CodePudding user response:
The error message clearly says that the @EnvironmentObject
property wrapper requires the associated object to be added to the environment somewhere on a higher level of the view hierarchy with the environmentObject()
modifier.
To access the view model directly you have to use @Stateobject
to create an instance of the observed class
@Stateobject var viewModel = AuthViewModel()