Thread 1: Fatal error: No ObservableObject of type
Thread 1: Fatal error: No ObservableObject of type
视频LinkYoutube
ConsoleError
Fatal error: No ObservableObject of type UserDefaultsConfig found. A View.environmentObject(_:) for UserDefaultsConfig may be missing as an ancestor of this view.: file SwiftUI, line 0
用户默认配置
class UserDefaultsConfig: ObservableObject {
@Published var allFavoriteMovie: [PopularMovie] = []
let defaults = UserDefaults.standard
func setUserDefaults(value: PopularMovie) {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(value) {
defaults.set(encoded, forKey: "favoriteMovie")
}
if let savedFavoriteMovie = defaults.object(forKey: "favoriteMovie") as? Data {
let decoder = JSONDecoder()
if let loadedFavMovie = try? decoder.decode(PopularMovie.self, from: savedFavoriteMovie) {
allFavoriteMovie.append(loadedFavMovie)
print("favMovie: \(allFavoriteMovie)")
}
}
}
}
首先打开 CustomTabView
CustomTabView
TabView(selection: $selectedTab) {
MainView(searchMovie: SearchMovieVM(), mainVM: MainVM())
.ignoresSafeArea()
.tag(TabCategory.movieList)
FavoriteView()
.ignoresSafeArea()
.tag(TabCategory.favorite)
}
我在 MainView 中单击 MovieCell 并将其定向到 DetailView。
主视图
NavigationLink(
destination: DetailView(movie: .constant(mainVM.popularMovie[movie])),
label: {
MovieCell(popularMovie: .constant(mainVM.popularMovie[movie]))
.foregroundColor(Color(UIColor.label))
})
DetailView
当我点击这里的按钮时,userDefaultsConfig 中的 setUserDefaults 函数是 运行。
struct DetailView: View {
....
@StateObject var userDefaultsConfig = UserDefaultsConfig()
var body: some View {
ZStack {
.....
ScrollView(.vertical, showsIndicators: false) {
.....
HStack {
Spacer()
Button(action: { self.userDefaultsConfig.setUserDefaults(value: movie) }) {
Image(systemName: "suit.heart")
.imageScale(.large)
.foregroundColor(.red)
}
}
....
}
.padding(.horizontal)
}
}
.environmentObject(userDefaultsConfig)
}
}
保存在DetailView页面UserDefaults中的电影会显示在收藏夹页面,但是打开收藏夹页面时出现错误。
收藏夹视图
struct FavoriteView: View {
@EnvironmentObject var userDefaultsConfig: UserDefaultsConfig
var body: some View {
VStack {
// ForEach(userDefaultsConfig.allFavoriteMovie, id: \.id) { item in
// Text(item.title ?? "")
// }
Text("")
.onAppear {
print(self.userDefaultsConfig.allFavoriteMovie)
}
}
}
}
你需要在CustomTabView
中放置状态对象,比如
struct CustomTabView: View {
....
@StateObject var userDefaultsConfig = UserDefaultsConfig()
...
TabView(selection: $selectedTab) {
MainView(searchMovie: SearchMovieVM(), mainVM: MainVM())
.ignoresSafeArea()
.tag(TabCategory.movieList)
FavoriteView()
.ignoresSafeArea()
.tag(TabCategory.favorite)
}
.environmentObject(userDefaultsConfig) // << here !!
...
并且在 DetailView
中只需将其用作环境对象,就像在 FavoriteView
中一样,即
struct DetailView: View {
@EnvironmentObject var userDefaultsConfig: UserDefaultsConfig
...
}
视频LinkYoutube
ConsoleError
Fatal error: No ObservableObject of type UserDefaultsConfig found. A View.environmentObject(_:) for UserDefaultsConfig may be missing as an ancestor of this view.: file SwiftUI, line 0
用户默认配置
class UserDefaultsConfig: ObservableObject {
@Published var allFavoriteMovie: [PopularMovie] = []
let defaults = UserDefaults.standard
func setUserDefaults(value: PopularMovie) {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(value) {
defaults.set(encoded, forKey: "favoriteMovie")
}
if let savedFavoriteMovie = defaults.object(forKey: "favoriteMovie") as? Data {
let decoder = JSONDecoder()
if let loadedFavMovie = try? decoder.decode(PopularMovie.self, from: savedFavoriteMovie) {
allFavoriteMovie.append(loadedFavMovie)
print("favMovie: \(allFavoriteMovie)")
}
}
}
}
首先打开 CustomTabView
CustomTabView
TabView(selection: $selectedTab) {
MainView(searchMovie: SearchMovieVM(), mainVM: MainVM())
.ignoresSafeArea()
.tag(TabCategory.movieList)
FavoriteView()
.ignoresSafeArea()
.tag(TabCategory.favorite)
}
我在 MainView 中单击 MovieCell 并将其定向到 DetailView。
主视图
NavigationLink(
destination: DetailView(movie: .constant(mainVM.popularMovie[movie])),
label: {
MovieCell(popularMovie: .constant(mainVM.popularMovie[movie]))
.foregroundColor(Color(UIColor.label))
})
DetailView
当我点击这里的按钮时,userDefaultsConfig 中的 setUserDefaults 函数是 运行。
struct DetailView: View {
....
@StateObject var userDefaultsConfig = UserDefaultsConfig()
var body: some View {
ZStack {
.....
ScrollView(.vertical, showsIndicators: false) {
.....
HStack {
Spacer()
Button(action: { self.userDefaultsConfig.setUserDefaults(value: movie) }) {
Image(systemName: "suit.heart")
.imageScale(.large)
.foregroundColor(.red)
}
}
....
}
.padding(.horizontal)
}
}
.environmentObject(userDefaultsConfig)
}
}
保存在DetailView页面UserDefaults中的电影会显示在收藏夹页面,但是打开收藏夹页面时出现错误。
收藏夹视图
struct FavoriteView: View {
@EnvironmentObject var userDefaultsConfig: UserDefaultsConfig
var body: some View {
VStack {
// ForEach(userDefaultsConfig.allFavoriteMovie, id: \.id) { item in
// Text(item.title ?? "")
// }
Text("")
.onAppear {
print(self.userDefaultsConfig.allFavoriteMovie)
}
}
}
}
你需要在CustomTabView
中放置状态对象,比如
struct CustomTabView: View {
....
@StateObject var userDefaultsConfig = UserDefaultsConfig()
...
TabView(selection: $selectedTab) {
MainView(searchMovie: SearchMovieVM(), mainVM: MainVM())
.ignoresSafeArea()
.tag(TabCategory.movieList)
FavoriteView()
.ignoresSafeArea()
.tag(TabCategory.favorite)
}
.environmentObject(userDefaultsConfig) // << here !!
...
并且在 DetailView
中只需将其用作环境对象,就像在 FavoriteView
中一样,即
struct DetailView: View {
@EnvironmentObject var userDefaultsConfig: UserDefaultsConfig
...
}