Как показать обложку MPMediaItem в списке SwiftUI? - PullRequest
1 голос
/ 17 октября 2019

Я пытаюсь создать SwiftUI Список всех локально сохраненных песен на моем iPhone. Я использую MediaPlayer Framework от Apple, чтобы получить песни и хранить их в EnvironmentObject для быстрого доступа в моем представлении SwiftUI.

Внутри моей ячейки я получаю доступ к изображению через, но все, что я получаю, это белый блок 50х50:

Image(uiImage: self.item.artwork!.image(at: CGSize(width: 50, height: 50))!)

Результат: https://i.imgur.com/gulvJ8u.png

// EnvironmentObject
class UserData: ObservableObject {

    @Published var allowMusicLibraryAccess: Bool = false
    @Published var songs: [MPMediaItem]

    init() {
        self.songs = [MPMediaItem]()

        self.initAllowMusicLibraryAccess()
    }

    private func initAllowMusicLibraryAccess() -> Void {
        MPMediaLibrary.requestAuthorization { status in
            if status == .authorized {
                DispatchQueue.main.async {
                    self.allowMusicLibraryAccess = true
                    self.songs = MPMediaQuery.songs().items!
                }
            }
        }
    }
}
// List
struct ContentView: View {

    @EnvironmentObject var userData: UserData

    var body: some View {
        ZStack() {
            if self.userData.allowMusicLibraryAccess {
                NavigationView {
                    List {
                        ForEach(self.userData.songs, id: \.persistentID) { song in
                            SongCell(song)
                        }
                    }
                    .navigationBarTitle("Songs")
                }
            } else {
                Text("Music Library Access needed")
            }
        }
    }
}
// Cell
struct SongCell: View {

    let item: MPMediaItem

    init(_ item: MPMediaItem) {
        self.item = item
    }

    var body: some View {

        Button(action: {
            print("clicked \(self.item)")
        }) {
            HStack() {
                if self.item.artwork != nil {
                    Image(uiImage: self.item.artwork!.image(at: CGSize(width: 50, height: 50))!)
                        .resizable()
                        .frame(width: 50, height: 50)
                        .cornerRadius(4)
                }

                VStack(alignment: .leading) {
                    Text(self.item.title ?? "---")

                    Text(self.item.artist ?? "---")
                        .font(.system(.footnote))
                        .opacity(0.7)
                }
            }
        }
        .frame(minWidth: nil, idealWidth: nil, maxWidth: .infinity, minHeight: 55, idealHeight: 55, maxHeight: 55, alignment: .leading)
    }
}

1 Ответ

0 голосов
/ 18 октября 2019

Я понял, но это похоже на ошибку или действительно интересное поведение инициализации, которое я не могу объяснить.

Я понял, что исправлено перемещение изображения из ячейки и непосредственно в список ForEach. эта проблема. Как я уже сказал, я не могу объяснить, почему это так.

// Cell
struct SongCell: View {

    let item: MPMediaItem

    init(_ item: MPMediaItem) {
        self.item = item
    }

    var body: some View {

        Button(action: {
            print("clicked \(self.item)")
        }) {
            VStack(alignment: .leading) {
                Text(self.item.title ?? "---")

                Text(self.item.artist ?? "---")
                    .font(.system(.footnote))
                    .opacity(0.7)
            }
        }
        .frame(minWidth: nil, idealWidth: nil, maxWidth: .infinity, minHeight: 55, idealHeight: 55, maxHeight: 55, alignment: .leading)
    }
}
// List
struct ContentView: View {

    @EnvironmentObject var userData: UserData

    var body: some View {
        ZStack() {
            if self.userData.allowMusicLibraryAccess {
                NavigationView {
                    List {
                        ForEach(self.userData.songs, id: \.persistentID) { song in
                            HStack() {
                                Image(uiImage: song.artwork!.image(at: CGSize(width: 50, height: 50))!)
                                    .resizable()
                                    .frame(width: 50, height: 50)
                                    .cornerRadius(4)
                                SongCell(song)
                            }    
                        } 
                    }
                    .navigationBarTitle("Songs")
                }
            } else {
                Text("Music Library Access needed")
            }
        }
     }
}
...