我一直在试图弄清楚如何将我的计算属性作为绑定从 foreach 循环传递到另一个视图,但我似乎无法弄清楚。我正在为 foreach 循环使用计算属性 b/c 它用于搜索栏。
问题是当我删除应用程序并重新安装它并且我在 albumView 中时,它不会刷新/更新,因为 CloudKit 正在将数据同步回应用程序。
首先让我展示我的 swift 数据模型。
import SwiftUI
import SwiftData
@Model
class Album: Identifiable {
var id: UUID = UUID()
var isPublicAlbum: Bool = false
var title: String = ""
var timeStamp: Date = Date()
@Relationship(deleteRule: .cascade, inverse: \Media.album) var media: [Media]?
init(isPublicAlbum: Bool, title: String, timeStamp: Date = Date()) {
self.isPublicAlbum = isPublicAlbum
self.title = title
self.timeStamp = timeStamp
}
}
import SwiftUI
import SwiftData
@Model
class Media: Identifiable {
var id: UUID = UUID()
var albumID: UUID = UUID()
@Attribute(.externalStorage) var asset: Data? = nil
var isCover: Bool = false
var contentType: String = ""
var timeStamp: Date = Date()
//var album: Album?
@Relationship(deleteRule: .nullify) var album: Album?
init(albumID: UUID = UUID(), asset: Data? = nil, isCover: Bool = false, contentType: String = "", timeStamp: Date = Date()) {
self.albumID = albumID
self.asset = asset
self.isCover = isCover
self.contentType = contentType
self.timeStamp = timeStamp
}
}
我将这样的上下文传递给所有子视图:
import SwiftData
class ModelContainerManager {
static let shared = ModelContainerManager()
let container: ModelContainer
private init() {
do {
container = try ModelContainer(for: User.self, Album.self, Media.self)
} catch {
fatalError(error.localizedDescription)
}
}
}
ContentView(……)
.modelContainer(ModelContainerManager.shared.container)
我希望能够将 albumID 作为绑定传递到 albumView,这样我就可以在 albumView 中使用
@Query
,希望我的 albumView 在与 Cloudkit 同步时能够实时更新。例如新的应用程序安装并且媒体正在下载。
这是相关代码。
struct MainView: View {
@Environment(\.modelContext) private var dbContext
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@Environment(\.colorScheme) var colorScheme
@Query(filter: #Predicate<Album> { $0.isPublicAlbum == false }, sort: \Album.title, order: .forward) private var listAlbums: [Album]
@State private var searchString: String = ""
private var filteredAlbums: [Album] {
if searchString.isEmpty {
return listAlbums
} else {
return listAlbums.filter { album in
album.title.localizedStandardContains(searchString)
}
}
}
//...
var body: some View {
VStack {
CustomSearchBar(text: $searchString, placeholder: NSLocalizedString("Search Private Albums", comment: "This is a search bar to search for private albums"))
//...
ForEach(filteredAlbums) { album in
VStack(spacing: 0) {
ZStack(alignment: .topTrailing) {
NavigationLink(destination: AlbumView(album: album)) {
//...
}
}
}
}
//...
}
}
}
无论我尝试了什么,我似乎都无法在没有编译器错误的情况下将专辑作为绑定传递,或者只是超时。我不想将其传递为
.constant(album)
b/c 我需要我的子视图实时更新,这是我的最终目标。
我目前在
let album: Album
中定义了 anlbumView
,并在 foreach 循环中使用 album.media
。关于如何实现这一目标有什么想法吗?
绑定用于写访问,因此您不应该使用它,因为 ID 永远不应该更改。你只需要
let album: Album
因为Album是一个模型,当你使用的任何属性发生变化时,body都会被调用。
一般来说,为 View 提供整个对象是一个坏主意,相反,您应该只传递 View 需要的内容,通过计算变量进行转换。这样,无需丰富的模型类型就可以预览视图。例如,将标题和艺术家传递给某些 LargeInfoView。