如何在 SwiftUI 列表中显示 MPMediaItem 图稿?
Posted
技术标签:
【中文标题】如何在 SwiftUI 列表中显示 MPMediaItem 图稿?【英文标题】:How to show MPMediaItem Artwork in a SwiftUI list? 【发布时间】:2019-10-17 14:49:39 【问题描述】:我尝试在我的 iPhone 上构建所有本地存储歌曲的 SwiftUI 列表。我使用 Apple 的 MediaPlayer 框架来获取歌曲并将它们存储在 EnvironmentObject 中,以便在我的 SwiftUI 视图中轻松访问。
在我的 Cell 中,我通过访问图像,但我得到的只是一个白色的 50x50 块:
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】:解决方法是使用 .renderingMode() 修饰符:
Image(uiImage: self.item.artwork!.image(at: CGSize(width: 50, height: 50))!)
.renderingMode(.original)
【讨论】:
【参考方案2】:我确实想通了,但它看起来有点像一个错误或一些我无法解释的非常有趣的初始化行为。
我发现将 Image 移出 Cell 并直接移入 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")
【讨论】:
以上是关于如何在 SwiftUI 列表中显示 MPMediaItem 图稿?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中使用 .fileimporter 保存音频文件并检索文件并在 SwiftUI 列表中显示它们的文件名?