4/// Show the names of the albums that a given asset is in.
6/// Each album is shown as a separate "pill" in the list, for example:
8/// [Cats] [Cross-stitch] [Stuff I did in 2023]
10struct AlbumInfoOverlay: ViewModifier {
11 var albums: [PHAssetCollection]
13 init(asset: PHAsset?) {
14 // Note: it's important to look up the list of albums here, and not
15 // defer it to the `body()` function.
17 // When Swift hears about a change to the Photos Library (e.g. adding
18 // a photo to an album), it will recreate this view, but if none of
19 // the data has changed it won't bother re-rendering. If the album
20 // lookup is inside `body()`, it never gets run because SwiftUI thinks
21 // the data is unchanged. Putting it here ensures we get fresh data.
22 self.albums = asset?.albums() ?? []
25 func body(content: Content) -> some View {
26 content.overlay(alignment: Alignment(horizontal: .center, vertical: .top)) {
28 ForEach(albums, id: \.localIdentifier) { album in
29 if let title = album.localizedTitle {
30 // Don't show the names of the meta-albums used to manage
32 if (title != "Approved" && title != "Rejected" && title != "Needs Action") {
34 // The icon was chosen to match the one used for albums
35 // in the sidebar in Photos.
36 Text("\(Image(systemName: "rectangle.stack")) \(title)")
40 .foregroundColor(.black)
41 .background(.white.opacity(0.9))
53 func albumInfo(for asset: PHAsset?) -> some View {
54 modifier(AlbumInfoOverlay(asset: asset))