当我尝试修复 SwiftUI 项目的预览时,如何将 'SongViewModel' 类型的值转换为预期的参数'SongViewModel'



所以基本上我正在尝试在SwiftUI与我最喜欢的歌曲列表的listView和detailView与navigationLink。我遇到了一些错误的动态数据,虽然它一直显示"无法找到"歌曲"在范围内",我正在努力寻找解决方案。谁能帮帮我,我真的很感激。

final class SongViewModel: ObservableObject {
private(set) var song: Song
init(song: Song) {
self.song = song
}
}
struct Song: Identifiable {
let id = UUID()
let imageName: String
let name: String
let songs = [
Song(imageName: "song1", name: "DJ NYK"),
Song(imageName: "song2", name: "John Wick Deconsecrated")
]
}

这就是SongViewModel

的代码在我的ContentView中当我尝试创建列表时它显示了这个错误

struct ContentView: View {
var body: some View {
List(songs) { song in
songRow(song: song)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

在我的detailView预览显示了这个错误DetailViewPreviewError

如果有人能帮我,我会很感激的。

我们在SwiftUI中不使用视图模型对象。我们使用@State,它使视图结构表现得像一个对象。试试这个:

struct Song: Identifiable {
let id = UUID()
let imageName: String
let name: String
}
struct ContentView: View {
@State var songs = [
Song(imageName: "song1", name: "DJ NYK"),
Song(imageName: "song2", name: "John Wick Deconsecrated")
]
var body: some View {
List(songs) { song in
SongView(song: song)
}
}
}
struct SongView: View {
let song: Song
var body: some View {
Text(song.name)
}
}

然而,通常歌曲将是模型数据而不是视图数据。这意味着数据的生命周期与屏幕上的内容无关,并且还可以使用不同的版本进行预览。它使用环境中的Store对象实现,如下所示:

class SongStore: ObservableObject {
static let shared = SongStore()
static let preview = SongStore(preview: true)
@Published var songs: [Song]
init(preview: Bool = false){
if preview == true {
songs = [Song(imageName: "song1", name: "DJ NYK"),
Song(imageName: "song2", name: "John Wick Deconsecrated")
]
}
else {
// load songs
}
}
func save() {
// save
}
}         
@main
struct SongApp: App {

var body: some Scene {
WindowGroup {
ContentView().environmentObject(SongStore.shared)
}
}
struct ContentView: View {
@EnvironmentObject var store: SongStore
var body: some View {
List(store.songs) { song in
SongView(song: song)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(SongStore.preview)
}
}

最新更新