Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to pass different objects and change view depending on what is passed?

I got two different Objects Song and Album. I got an AlbumView with a @State var album: Album and I want to reuse that View but pass a Song instead. Is it possible to pass either Album or Song? Otherwise it would also be helpful if I could set Album to nil and then just check in the View whether it has a value.

This is what Album looks like:

struct Album: Identifiable {
    let id = UUID()
    let name: String
    let artist: String
    let songs: [AlbumSong]
    let releaseDate: Date
    let price: Int
    let albumImageUrl: String
    var unlocked: Bool
}

This is what Song looks like:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

struct Song: Identifiable, Codable {
    let id = UUID()
    let title: String
    let duration: TimeInterval
    var image: String
    let artist: String
    let track: String
    let price: Int
}

This is my AlbumView:

struct AlbumView: View {
@State var album: Album

var body: some View {
   Text("\(album.name)").font(.system(size: 18))
   }
}
      

This would be my idea to solve it with passing one object as nil:

struct AlbumView: View {
    @State var album: Album?
    @State var song: Song
    
    var body: some View {
        if album != nil {
            Text("\(album!.name)")
        } else {
            Text("\(song.name)")
        }
    }
}

>Solution :

There are multiple ways to do this:

Enum

enum SomeType {
    case song(Song)
    case album(Album)
}

Then in your View you pass a type to AlbumView & display it like so:

struct AlbumView: View {
    @State var type: SomeType
    var body: some View {
       switch type {
           case .album(let album):
               Text("\(album.name)")
           case .song(let song):
               Text("\(song.name)")
       }
   }
}

You pass the type like so:

AlbumView(type: .album(someAlbum))//for albums
AlbumView(type: .song(someSong))//for songs

Protocol

If you’re using shared property names:

protocol SomeMedia {
    var name: String {get set}
    //any other shared property
}

struct AlbumView: View {
    @State var media: SomeMedia
    var body: some View {
        Text("\(media.name)")
    }
}

Make Album & Song conform to SomeMedia, then you can pass a song or an album as you require!

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading