ios - 如何在 SwiftUI 列表中显示 MPMediaItem 图稿?

标签 ios swift swiftui mpmediaitem mpmediaquery

我尝试构建一个包含 iPhone 上所有本地存储歌曲的 SwiftUI 列表。我使用 Apple 的 MediaPlayer 框架来获取歌曲并将它们存储在 EnvironmentObject 中,以便在我的 SwiftUI View 中轻松访问。

在我的 Cell 中,我通过以下方式访问图像,但我得到的只是一个白色的 50x50 block :

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

结果:/image/eQXCN.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)
    }
}

最佳答案

我确实弄清楚了,但它看起来有点像一个错误或一些我无法解释的非常有趣的初始化行为。

我发现将图像移出单元格并直接移入 List 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")
            }
        }
     }
}

关于ios - 如何在 SwiftUI 列表中显示 MPMediaItem 图稿?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58435382/

相关文章:

ios - 将计时器标签格式化为小时 :minutes:seconds in Swift

swift - Spritekit : Change a scene and keep the background

ios - 如何使用 SwiftUI 在 NavigationView 中正确包含 "Add Item"按钮?

javascript - 如何在 React Native 中将事件从 iOS 发送到 javascript

objective-c - 如何将核心数据添加到现有的基于选项卡的 IOS 项目

objective-c - 有什么方法可以加粗 NSString 的一部分?

ios - 代码 : failed to get the task for process

swift - 来自 String 的 NSURL 被截断,UIVideoEditorController 的视频路径上的点 Swift 2 iOS 8

ios - 无法更改 SwiftUI 上的暗模式

swift - SwiftUI 中按钮和图像的可点击区域