我目前正在编写应用程序但无法弄清楚如何将此特定Objective-C行转换为swift。任何帮助都感激不尽。我已经能够很好地翻译其他行,但是这个会抛出一些异常错误。这是最初的Objective-C系列:
MPMediaItem * rowItem = [songs objectAtIndex:indexPath.row];
我是菜鸟,并尝试了很多变种,包括:
var rowItem = songs.objectAtIndex(indexPath.row)as MPMediaItem
和
var rowItem:MPMediaItem = songs.objectAtIndex(indexPath.row)as MPMediaItem
但是我已经这么久了,我看不出它应该是什么。非常感谢!
编辑:
歌曲定义为:
让songsQuery = MPMediaQuery.songsQuery()
让songs = [songsQuery.items]为NSArray
我刚收到exe_breakpoint错误。如果我通过使用...作为[MPMediaItem]将MPMediaItem封装在一个数组中,我可以通过这个,但是我无法获得属性值,例如MPMediaItemPropertyTitle和MPMediaItemPropertyArtist。
更新: 设法通过使用for循环获得MPMediaItemPropertyTitle和MPMediaPropertyArtist来使其工作。 'songs'变量定义如上所述。 @Antonio,删除括号不起作用。这是我目前的代码:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
// Configure the cell...
let songsQuery = MPMediaQuery.songsQuery()
let allSongsArray = [songsQuery.items] as NSArray
var singleItem: AnyObject = allSongsArray[indexPath.row]
var rowItem = singleItem as [MPMediaItem]
if rowItem.count > 0 {
cell.textLabel?.text = rowItem[0].valueForProperty(MPMediaItemPropertyTitle) as NSString
cell.detailTextLabel?.text = rowItem[0].valueForProperty(MPMediaItemPropertyArtist) as NSString
}
return cell
}
我现在遇到的问题是,当我测试应用程序时,它只显示我库中的第一首歌,并没有列出它应该的每首歌曲。感谢您提供任何帮助!
更新2:
使用以下代码:
class SongsViewController: UITableViewController {
var allSongs : [MPMediaItem] = []
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
allSongs += MPMediaQuery.songsQuery().items as [MPMediaItem]
println(allSongs.count)
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return allSongs.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
// Configure the cell...
var rowItem = allSongs[indexPath.row]
cell.textLabel?.text = rowItem.valueForProperty(MPMediaItemPropertyTitle) as NSString
cell.detailTextLabel?.text = rowItem.valueForProperty(MPMediaItemPropertyArtist) as NSString
return cell
}
答案 0 :(得分:0)
let allSongsArray = [songsQuery.items] as NSArray
在这里你拿一个Array<AnyObject>!
并将它包装在另一个Array
中,然后再将其转换为NSArray ......非常混乱。
试试这个:
let songsQuery = MPMediaQuery.songsQuery()
let allSongs = songsQuery.items as [MPMediaItem]
let song = allSongs[indexPath.row]
cell.textLabel?.text = song.valueForProperty(MPMediaItemPropertyTitle) as String
cell.detailTextLabel?.text = song.valueForProperty(MPMediaItemPropertyArtist) as String
此外,您确实应该缓存allSongs
,而不是每次需要填充单元格时查询它。要执行此操作,只需创建向控制器添加var allSongs: [MPMediaItem] = []
即可。然后在例如viewDidLoad
中使用MPMediaQuery来填充该数组。然后,您可以在任何表视图委托和数据源方法中使用该数组。
答案 1 :(得分:0)
我认为您所犯的错误是在cellForRowAtIndexPath
中加载整个数据源,而这应该在另一个地方完成(viewDidLoad
是一个很好的候选者),而且最重要的是一次而不是每一行。
我已经重新编写了代码,我已经提出了这段代码:
class TestViewController : UITableViewController {
var allSongsArray: [MPMediaItem]!
override func viewDidLoad() {
super.viewDidLoad()
let songsQuery = MPMediaQuery.songsQuery()
self.allSongsArray = songsQuery.items as [MPMediaItem]
// Other initializations
...
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.allSongsArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
var rowItem = self.allSongsArray[indexPath.row]
cell.textLabel?.text = rowItem[0].valueForProperty(MPMediaItemPropertyTitle) as NSString
cell.detailTextLabel?.text = rowItem[0].valueForProperty(MPMediaItemPropertyArtist) as NSString
return cell
}
}
答案 2 :(得分:0)
var allSongs : [MPMediaItem] = []
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
allSongs += MPMediaQuery.songsQuery().items as [MPMediaItem]
println(allSongs.count)
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return allSongs.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
// Configure the cell...
var rowItem = allSongs[indexPath.row]
cell.textLabel?.text = rowItem.valueForProperty(MPMediaItemPropertyTitle) as NSString
cell.detailTextLabel?.text = rowItem.valueForProperty(MPMediaItemPropertyArtist) as NSString
return cell
}